refactor: API changes
This commit is contained in:
parent
7ec6a44926
commit
f71fdac166
|
@ -7,7 +7,6 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
|||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.feed.FeedExtractor;
|
||||
import org.schabi.newpipe.extractor.kiosk.KioskList;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
|
@ -146,6 +145,14 @@ public abstract class StreamingService {
|
|||
*/
|
||||
public abstract ListLinkHandlerFactory getChannelLHFactory();
|
||||
|
||||
/**
|
||||
* Must return a new instance of an implementation of ListLinkHandlerFactory for channel tabs.
|
||||
* If support for channel tabs is not given null must be returned.
|
||||
*
|
||||
* @return an instance of a ListLinkHandlerFactory for channels or null
|
||||
*/
|
||||
public abstract ListLinkHandlerFactory getChannelTabLHFactory();
|
||||
|
||||
/**
|
||||
* Must return a new instance of an implementation of ListLinkHandlerFactory for playlists.
|
||||
* If support for playlists is not given null must be returned.
|
||||
|
@ -218,7 +225,13 @@ public abstract class StreamingService {
|
|||
public abstract ChannelExtractor getChannelExtractor(ListLinkHandler linkHandler)
|
||||
throws ExtractionException;
|
||||
|
||||
public abstract ChannelTabExtractor getChannelTabExtractor(ChannelTabHandler linkHandler)
|
||||
/**
|
||||
* Must create a new instance of a ChannelTabExtractor implementation.
|
||||
*
|
||||
* @param linkHandler is pointing to the channel which should be handled by this new instance.
|
||||
* @return a new ChannelTabExtractor
|
||||
*/
|
||||
public abstract ChannelTabExtractor getChannelTabExtractor(ListLinkHandler linkHandler)
|
||||
throws ExtractionException;
|
||||
|
||||
/**
|
||||
|
@ -261,17 +274,17 @@ public abstract class StreamingService {
|
|||
.fromQuery(id, contentFilter, sortFilter));
|
||||
}
|
||||
|
||||
public ChannelTabExtractor getChannelTabExtractorFromUrl(final String url,
|
||||
final ChannelTabHandler.Tab tab)
|
||||
public ChannelTabExtractor getChannelTabExtractorFromId(final String id, final String tab)
|
||||
throws ExtractionException {
|
||||
return getChannelTabExtractor(
|
||||
new ChannelTabHandler(getChannelLHFactory().fromUrl(url), tab));
|
||||
return getChannelTabExtractor(getChannelTabLHFactory().fromQuery(
|
||||
id, Collections.singletonList(tab), ""));
|
||||
}
|
||||
|
||||
public ChannelTabExtractor getChannelTabExtractorFromId(final String id,
|
||||
final ChannelTabHandler.Tab tab)
|
||||
public ChannelTabExtractor getChannelTabExtractorFromId(final String id, final String tab,
|
||||
final String baseUrl)
|
||||
throws ExtractionException {
|
||||
return getChannelTabExtractor(new ChannelTabHandler(getChannelLHFactory().fromId(id), tab));
|
||||
return getChannelTabExtractor(getChannelTabLHFactory().fromQuery(
|
||||
id, Collections.singletonList(tab), "", baseUrl));
|
||||
}
|
||||
|
||||
public PlaylistExtractor getPlaylistExtractor(final String id,
|
||||
|
|
|
@ -3,7 +3,6 @@ package org.schabi.newpipe.extractor.channel;
|
|||
import org.schabi.newpipe.extractor.ListExtractor;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
|
||||
|
@ -49,7 +48,7 @@ public abstract class ChannelExtractor extends ListExtractor<StreamInfoItem> {
|
|||
public abstract String getParentChannelAvatarUrl() throws ParsingException;
|
||||
public abstract boolean isVerified() throws ParsingException;
|
||||
@Nonnull
|
||||
public List<ChannelTabHandler> getTabs() throws ParsingException {
|
||||
public List<ListLinkHandler> getTabs() throws ParsingException {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@Nonnull
|
||||
|
|
|
@ -6,7 +6,6 @@ import org.schabi.newpipe.extractor.NewPipe;
|
|||
import org.schabi.newpipe.extractor.Page;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.utils.ExtractorHelper;
|
||||
|
@ -159,7 +158,7 @@ public class ChannelInfo extends ListInfo<StreamInfoItem> {
|
|||
private String[] donationLinks;
|
||||
private boolean verified;
|
||||
|
||||
private List<ChannelTabHandler> tabs = Collections.emptyList();
|
||||
private List<ListLinkHandler> tabs = Collections.emptyList();
|
||||
|
||||
private List<String> tags = Collections.emptyList();
|
||||
|
||||
|
@ -244,11 +243,11 @@ public class ChannelInfo extends ListInfo<StreamInfoItem> {
|
|||
}
|
||||
|
||||
@Nonnull
|
||||
public List<ChannelTabHandler> getTabs() {
|
||||
public List<ListLinkHandler> getTabs() {
|
||||
return tabs;
|
||||
}
|
||||
|
||||
public void setTabs(@Nonnull final List<ChannelTabHandler> tabs) {
|
||||
public void setTabs(@Nonnull final List<ListLinkHandler> tabs) {
|
||||
this.tabs = tabs;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,31 +4,24 @@ import org.schabi.newpipe.extractor.InfoItem;
|
|||
import org.schabi.newpipe.extractor.ListExtractor;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public abstract class ChannelTabExtractor extends ListExtractor<InfoItem> {
|
||||
|
||||
public ChannelTabExtractor(final StreamingService service,
|
||||
final ChannelTabHandler linkHandler) {
|
||||
final ListLinkHandler linkHandler) {
|
||||
super(service, linkHandler);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ChannelTabHandler getLinkHandler() {
|
||||
return (ChannelTabHandler) super.getLinkHandler();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public ChannelTabHandler.Tab getTab() {
|
||||
return getLinkHandler().getTab();
|
||||
public String getTab() {
|
||||
return getLinkHandler().getContentFilters().get(0);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getName() throws ParsingException {
|
||||
return getTab().name();
|
||||
return getTab();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,18 +6,18 @@ import org.schabi.newpipe.extractor.ListInfo;
|
|||
import org.schabi.newpipe.extractor.Page;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.utils.ExtractorHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ChannelTabInfo extends ListInfo<InfoItem> {
|
||||
public ChannelTabInfo(final int serviceId, final ChannelTabHandler linkHandler) {
|
||||
super(serviceId, linkHandler, linkHandler.getTab().name());
|
||||
public ChannelTabInfo(final int serviceId, final ListLinkHandler linkHandler) {
|
||||
super(serviceId, linkHandler, linkHandler.getContentFilters().get(0));
|
||||
}
|
||||
|
||||
public static ChannelTabInfo getInfo(final StreamingService service,
|
||||
final ChannelTabHandler linkHandler)
|
||||
final ListLinkHandler linkHandler)
|
||||
throws ExtractionException, IOException {
|
||||
final ChannelTabExtractor extractor = service.getChannelTabExtractor(linkHandler);
|
||||
extractor.fetchPage();
|
||||
|
@ -43,7 +43,7 @@ public class ChannelTabInfo extends ListInfo<InfoItem> {
|
|||
}
|
||||
|
||||
public static ListExtractor.InfoItemsPage<InfoItem> getMoreItems(
|
||||
final StreamingService service, final ChannelTabHandler linkHandler, final Page page)
|
||||
final StreamingService service, final ListLinkHandler linkHandler, final Page page)
|
||||
throws ExtractionException, IOException {
|
||||
return service.getChannelTabExtractor(linkHandler).getPage(page);
|
||||
}
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
package org.schabi.newpipe.extractor.linkhandler;
|
||||
|
||||
public class ChannelTabHandler extends ListLinkHandler {
|
||||
public enum Tab {
|
||||
Playlists,
|
||||
Livestreams,
|
||||
Shorts,
|
||||
Channels,
|
||||
Albums,
|
||||
}
|
||||
|
||||
private final Tab tab;
|
||||
|
||||
public ChannelTabHandler(final ListLinkHandler linkHandler, final Tab tab) {
|
||||
super(linkHandler);
|
||||
this.tab = tab;
|
||||
}
|
||||
|
||||
public Tab getTab() {
|
||||
return tab;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.schabi.newpipe.extractor.linkhandler;
|
||||
|
||||
public final class ChannelTabs {
|
||||
public static final String SHORTS = "shorts";
|
||||
public static final String LIVE = "live";
|
||||
public static final String CHANNELS = "channels";
|
||||
public static final String PLAYLISTS = "playlists";
|
||||
public static final String ALBUMS = "albums";
|
||||
|
||||
private ChannelTabs() {
|
||||
}
|
||||
}
|
|
@ -8,7 +8,6 @@ import org.schabi.newpipe.extractor.channel.ChannelTabExtractor;
|
|||
import org.schabi.newpipe.extractor.comments.CommentsExtractor;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.kiosk.KioskList;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
|
@ -29,6 +28,7 @@ import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampSearchE
|
|||
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampStreamExtractor;
|
||||
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampSuggestionExtractor;
|
||||
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampChannelLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampChannelTabLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampCommentsLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampFeaturedLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampPlaylistLinkHandlerFactory;
|
||||
|
@ -66,7 +66,12 @@ public class BandcampService extends StreamingService {
|
|||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getChannelLHFactory() {
|
||||
return new BandcampChannelLinkHandlerFactory();
|
||||
return BandcampChannelLinkHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getChannelTabLHFactory() {
|
||||
return BandcampChannelTabLinkHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -140,7 +145,7 @@ public class BandcampService extends StreamingService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ChannelTabExtractor getChannelTabExtractor(final ChannelTabHandler linkHandler) {
|
||||
public ChannelTabExtractor getChannelTabExtractor(final ListLinkHandler linkHandler) {
|
||||
return new BandcampChannelTabExtractor(this, linkHandler);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import org.schabi.newpipe.extractor.downloader.Downloader;
|
|||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.services.bandcamp.extractors.streaminfoitem.BandcampDiscographStreamInfoItemExtractor;
|
||||
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampChannelTabHandler;
|
||||
|
@ -109,14 +109,15 @@ public class BandcampChannelExtractor extends ChannelExtractor {
|
|||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<ChannelTabHandler> getTabs() throws ParsingException {
|
||||
public List<ListLinkHandler> getTabs() throws ParsingException {
|
||||
final JsonArray discography = channelInfo.getArray("discography");
|
||||
|
||||
if (discography.stream().anyMatch(o -> (
|
||||
(JsonObject) o).getString("item_type").equals("album"))) {
|
||||
final ListLinkHandler lh = getLinkHandler();
|
||||
return Collections.singletonList(
|
||||
new BandcampChannelTabHandler(getLinkHandler(),
|
||||
ChannelTabHandler.Tab.Albums, discography));
|
||||
new BandcampChannelTabHandler(lh.getUrl(), lh.getId(),
|
||||
ChannelTabs.ALBUMS, discography));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ import org.schabi.newpipe.extractor.StreamingService;
|
|||
import org.schabi.newpipe.extractor.channel.ChannelTabExtractor;
|
||||
import org.schabi.newpipe.extractor.downloader.Downloader;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampChannelTabHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
@ -17,13 +18,13 @@ import java.io.IOException;
|
|||
|
||||
public class BandcampChannelTabExtractor extends ChannelTabExtractor {
|
||||
public BandcampChannelTabExtractor(final StreamingService service,
|
||||
final ChannelTabHandler linkHandler) {
|
||||
final ListLinkHandler linkHandler) {
|
||||
super(service, linkHandler);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private JsonArray getDiscographs() throws ExtractionException {
|
||||
final ChannelTabHandler tabHandler = getLinkHandler();
|
||||
final ListLinkHandler tabHandler = getLinkHandler();
|
||||
if (tabHandler instanceof BandcampChannelTabHandler) {
|
||||
return ((BandcampChannelTabHandler) tabHandler).getDiscographs();
|
||||
} else {
|
||||
|
@ -34,9 +35,8 @@ public class BandcampChannelTabExtractor extends ChannelTabExtractor {
|
|||
|
||||
@Override
|
||||
public void onFetchPage(@Nonnull final Downloader downloader) {
|
||||
if (getLinkHandler().getTab() != ChannelTabHandler.Tab.Albums) {
|
||||
throw new IllegalArgumentException(
|
||||
"tab " + getLinkHandler().getTab().name() + " not supported");
|
||||
if (!getTab().equals(ChannelTabs.ALBUMS)) {
|
||||
throw new IllegalArgumentException("tab " + getTab() + " not supported");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,16 @@ import java.util.List;
|
|||
/**
|
||||
* Artist do have IDs that are useful
|
||||
*/
|
||||
public class BandcampChannelLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
public final class BandcampChannelLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
private static final BandcampChannelLinkHandlerFactory INSTANCE
|
||||
= new BandcampChannelLinkHandlerFactory();
|
||||
|
||||
private BandcampChannelLinkHandlerFactory() {
|
||||
}
|
||||
|
||||
public static BandcampChannelLinkHandlerFactory getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(final String url) throws ParsingException {
|
||||
|
@ -31,7 +39,7 @@ public class BandcampChannelLinkHandlerFactory extends ListLinkHandlerFactory {
|
|||
return String.valueOf(bandData.getLong("id"));
|
||||
|
||||
} catch (final IOException | ReCaptchaException | ArrayIndexOutOfBoundsException
|
||||
| JsonParserException e) {
|
||||
| JsonParserException e) {
|
||||
throw new ParsingException("Download failed", e);
|
||||
}
|
||||
}
|
||||
|
@ -73,6 +81,7 @@ public class BandcampChannelLinkHandlerFactory extends ListLinkHandlerFactory {
|
|||
// Must have "releases" or "music" as segment after url or none at all
|
||||
if (splitUrl.length > 3 && !(
|
||||
splitUrl[3].equals("releases") || splitUrl[3].equals("music")
|
||||
|| (splitUrl[3].equals("album") && splitUrl.length == 4)
|
||||
)) {
|
||||
|
||||
return false;
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
package org.schabi.newpipe.extractor.services.bandcamp.linkHandler;
|
||||
|
||||
import com.grack.nanojson.JsonArray;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
|
||||
public class BandcampChannelTabHandler extends ChannelTabHandler {
|
||||
import java.util.Collections;
|
||||
|
||||
public class BandcampChannelTabHandler extends ListLinkHandler {
|
||||
private final JsonArray discographs;
|
||||
|
||||
public BandcampChannelTabHandler(final ListLinkHandler linkHandler, final Tab tab,
|
||||
public BandcampChannelTabHandler(final String url, final String id, final String tab,
|
||||
final JsonArray discographs) {
|
||||
super(linkHandler, tab);
|
||||
super(url, url, id, Collections.singletonList(tab), "");
|
||||
this.discographs = discographs;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package org.schabi.newpipe.extractor.services.bandcamp.linkHandler;
|
||||
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class BandcampChannelTabLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
private static final BandcampChannelTabLinkHandlerFactory INSTANCE
|
||||
= new BandcampChannelTabLinkHandlerFactory();
|
||||
|
||||
private BandcampChannelTabLinkHandlerFactory() {
|
||||
}
|
||||
|
||||
public static BandcampChannelTabLinkHandlerFactory getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(final String url) throws ParsingException {
|
||||
return BandcampChannelLinkHandlerFactory.getInstance().getId(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(final String id, final List<String> contentFilter, final String sortFilter)
|
||||
throws ParsingException {
|
||||
final String tab = contentFilter.get(0);
|
||||
if (!tab.equals(ChannelTabs.ALBUMS)) {
|
||||
throw new ParsingException("tab " + tab + " not supported");
|
||||
}
|
||||
|
||||
// This is not an actual page on the Bandcamp website, but it auto-redirects
|
||||
// to the main page and we need a unique URL for the album tab
|
||||
return BandcampChannelLinkHandlerFactory.getInstance().getUrl(id) + "/album";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onAcceptUrl(final String url) throws ParsingException {
|
||||
return BandcampChannelLinkHandlerFactory.getInstance().onAcceptUrl(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAvailableContentFilter() {
|
||||
return new String[] {
|
||||
ChannelTabs.ALBUMS,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@ import org.schabi.newpipe.extractor.channel.ChannelTabExtractor;
|
|||
import org.schabi.newpipe.extractor.comments.CommentsExtractor;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.kiosk.KioskList;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
|
@ -57,6 +56,11 @@ public class MediaCCCService extends StreamingService {
|
|||
return new MediaCCCConferenceLinkHandlerFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getChannelTabLHFactory() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getPlaylistLHFactory() {
|
||||
return null;
|
||||
|
@ -81,7 +85,7 @@ public class MediaCCCService extends StreamingService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ChannelTabExtractor getChannelTabExtractor(final ChannelTabHandler linkHandler)
|
||||
public ChannelTabExtractor getChannelTabExtractor(final ListLinkHandler linkHandler)
|
||||
throws ExtractionException {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
|||
import org.schabi.newpipe.extractor.downloader.Downloader;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.services.media_ccc.extractors.infoItems.MediaCCCStreamInfoItemExtractor;
|
||||
import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCConferenceLinkHandlerFactory;
|
||||
|
@ -77,7 +76,7 @@ public class MediaCCCConferenceExtractor extends ChannelExtractor {
|
|||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<ChannelTabHandler> getTabs() {
|
||||
public List<ListLinkHandler> getTabs() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,9 @@ import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
|||
import org.schabi.newpipe.extractor.channel.ChannelTabExtractor;
|
||||
import org.schabi.newpipe.extractor.comments.CommentsExtractor;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.kiosk.KioskList;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
|
@ -26,6 +27,7 @@ import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeStreamE
|
|||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeSuggestionExtractor;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeTrendingExtractor;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelTabLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeCommentsLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubePlaylistLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeSearchQueryHandlerFactory;
|
||||
|
@ -64,6 +66,11 @@ public class PeertubeService extends StreamingService {
|
|||
return PeertubeChannelLinkHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getChannelTabLHFactory() {
|
||||
return PeertubeChannelTabLinkHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getPlaylistLHFactory() {
|
||||
return PeertubePlaylistLinkHandlerFactory.getInstance();
|
||||
|
@ -108,13 +115,16 @@ public class PeertubeService extends StreamingService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ChannelTabExtractor getChannelTabExtractor(final ChannelTabHandler linkHandler)
|
||||
public ChannelTabExtractor getChannelTabExtractor(final ListLinkHandler linkHandler)
|
||||
throws ExtractionException {
|
||||
if (linkHandler.getUrl().contains("/video-channels/")) {
|
||||
return new PeertubeChannelTabExtractor(this, linkHandler);
|
||||
} else {
|
||||
return new PeertubeAccountTabExtractor(this, linkHandler);
|
||||
final String tab = linkHandler.getContentFilters().get(0);
|
||||
switch (tab) {
|
||||
case ChannelTabs.CHANNELS:
|
||||
return new PeertubeAccountTabExtractor(this, linkHandler);
|
||||
case ChannelTabs.PLAYLISTS:
|
||||
return new PeertubeChannelTabExtractor(this, linkHandler);
|
||||
}
|
||||
throw new ParsingException("tab " + tab + " not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,7 +12,7 @@ import org.schabi.newpipe.extractor.downloader.Response;
|
|||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelLinkHandlerFactory;
|
||||
|
@ -124,9 +124,11 @@ public class PeertubeAccountExtractor extends ChannelExtractor {
|
|||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<ChannelTabHandler> getTabs() {
|
||||
public List<ListLinkHandler> getTabs() throws ParsingException {
|
||||
return Collections.singletonList(
|
||||
new ChannelTabHandler(getLinkHandler(), ChannelTabHandler.Tab.Channels));
|
||||
new ListLinkHandler(getOriginalUrl(), getUrl(), getId(),
|
||||
Collections.singletonList(ChannelTabs.CHANNELS), "")
|
||||
);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
|
|
@ -12,7 +12,8 @@ import org.schabi.newpipe.extractor.downloader.Downloader;
|
|||
import org.schabi.newpipe.extractor.downloader.Response;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.utils.Utils;
|
||||
|
@ -30,17 +31,16 @@ public class PeertubeAccountTabExtractor extends ChannelTabExtractor {
|
|||
private static final String ACCOUNTS = "accounts/";
|
||||
|
||||
public PeertubeAccountTabExtractor(final StreamingService service,
|
||||
final ChannelTabHandler linkHandler)
|
||||
final ListLinkHandler linkHandler)
|
||||
throws ParsingException {
|
||||
super(service, linkHandler);
|
||||
baseUrl = getBaseUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchPage(final @Nonnull Downloader downloader) {
|
||||
if (getLinkHandler().getTab() != ChannelTabHandler.Tab.Channels) {
|
||||
throw new IllegalArgumentException(
|
||||
"tab " + getLinkHandler().getTab().name() + " not supported");
|
||||
public void onFetchPage(final @Nonnull Downloader downloader) throws ParsingException {
|
||||
if (!getTab().equals(ChannelTabs.CHANNELS)) {
|
||||
throw new ParsingException("tab " + getTab() + " not supported");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import org.schabi.newpipe.extractor.downloader.Downloader;
|
|||
import org.schabi.newpipe.extractor.downloader.Response;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelLinkHandlerFactory;
|
||||
|
@ -103,9 +103,11 @@ public class PeertubeChannelExtractor extends ChannelExtractor {
|
|||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<ChannelTabHandler> getTabs() {
|
||||
public List<ListLinkHandler> getTabs() throws ParsingException {
|
||||
return Collections.singletonList(
|
||||
new ChannelTabHandler(getLinkHandler(), ChannelTabHandler.Tab.Playlists));
|
||||
new ListLinkHandler(getOriginalUrl(), getUrl(), getId(),
|
||||
Collections.singletonList(ChannelTabs.PLAYLISTS), "")
|
||||
);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
|
|
@ -12,7 +12,8 @@ import org.schabi.newpipe.extractor.downloader.Downloader;
|
|||
import org.schabi.newpipe.extractor.downloader.Response;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.utils.Utils;
|
||||
|
@ -29,17 +30,16 @@ public class PeertubeChannelTabExtractor extends ChannelTabExtractor {
|
|||
private final String baseUrl;
|
||||
|
||||
public PeertubeChannelTabExtractor(final StreamingService service,
|
||||
final ChannelTabHandler linkHandler)
|
||||
final ListLinkHandler linkHandler)
|
||||
throws ParsingException {
|
||||
super(service, linkHandler);
|
||||
baseUrl = getBaseUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchPage(final @Nonnull Downloader downloader) {
|
||||
if (getLinkHandler().getTab() != ChannelTabHandler.Tab.Playlists) {
|
||||
throw new IllegalArgumentException(
|
||||
"tab " + getLinkHandler().getTab().name() + " not supported");
|
||||
public void onFetchPage(final @Nonnull Downloader downloader) throws ParsingException {
|
||||
if (!getTab().equals(ChannelTabs.PLAYLISTS)) {
|
||||
throw new ParsingException("tab " + getTab() + " not supported");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.linkHandler;
|
||||
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class PeertubeChannelTabLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
private static final PeertubeChannelTabLinkHandlerFactory INSTANCE
|
||||
= new PeertubeChannelTabLinkHandlerFactory();
|
||||
|
||||
private PeertubeChannelTabLinkHandlerFactory() {
|
||||
}
|
||||
|
||||
public static PeertubeChannelTabLinkHandlerFactory getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private static String getUrlSuffix(final String tab) throws ParsingException {
|
||||
switch (tab) {
|
||||
case ChannelTabs.PLAYLISTS:
|
||||
return "/video-playlists";
|
||||
case ChannelTabs.CHANNELS:
|
||||
return "/video-channels";
|
||||
}
|
||||
throw new ParsingException("tab " + tab + " not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(final String url) throws ParsingException {
|
||||
return PeertubeChannelLinkHandlerFactory.getInstance().getId(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(final String id, final List<String> contentFilter, final String sortFilter)
|
||||
throws ParsingException {
|
||||
return PeertubeChannelLinkHandlerFactory.getInstance().getUrl(id)
|
||||
+ getUrlSuffix(contentFilter.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(final String id, final List<String> contentFilter, final String sortFilter,
|
||||
final String baseUrl) throws ParsingException {
|
||||
return PeertubeChannelLinkHandlerFactory.getInstance().getUrl(id, null, null, baseUrl)
|
||||
+ getUrlSuffix(contentFilter.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onAcceptUrl(final String url) throws ParsingException {
|
||||
return PeertubeChannelLinkHandlerFactory.getInstance().onAcceptUrl(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAvailableContentFilter() {
|
||||
return new String[] {
|
||||
ChannelTabs.PLAYLISTS,
|
||||
ChannelTabs.CHANNELS,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@ import org.schabi.newpipe.extractor.channel.ChannelTabExtractor;
|
|||
import org.schabi.newpipe.extractor.comments.CommentsExtractor;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.kiosk.KioskList;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
|
@ -26,6 +25,7 @@ import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudStr
|
|||
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudSubscriptionExtractor;
|
||||
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudSuggestionExtractor;
|
||||
import org.schabi.newpipe.extractor.services.soundcloud.linkHandler.SoundcloudChannelLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.soundcloud.linkHandler.SoundcloudChannelTabLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.soundcloud.linkHandler.SoundcloudChartsLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.soundcloud.linkHandler.SoundcloudCommentsLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.soundcloud.linkHandler.SoundcloudPlaylistLinkHandlerFactory;
|
||||
|
@ -66,6 +66,11 @@ public class SoundcloudService extends StreamingService {
|
|||
return SoundcloudChannelLinkHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getChannelTabLHFactory() {
|
||||
return SoundcloudChannelTabLinkHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getPlaylistLHFactory() {
|
||||
return SoundcloudPlaylistLinkHandlerFactory.getInstance();
|
||||
|
@ -90,7 +95,7 @@ public class SoundcloudService extends StreamingService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ChannelTabExtractor getChannelTabExtractor(final ChannelTabHandler linkHandler) {
|
||||
public ChannelTabExtractor getChannelTabExtractor(final ListLinkHandler linkHandler) {
|
||||
return new SoundcloudChannelTabExtractor(this, linkHandler);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
|||
import org.schabi.newpipe.extractor.downloader.Downloader;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.services.soundcloud.SoundcloudParsingHelper;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
|
@ -18,6 +18,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
|||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.schabi.newpipe.extractor.services.soundcloud.SoundcloudParsingHelper.SOUNDCLOUD_API_V2_URL;
|
||||
|
@ -109,10 +110,13 @@ public class SoundcloudChannelExtractor extends ChannelExtractor {
|
|||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<ChannelTabHandler> getTabs() throws ParsingException {
|
||||
public List<ListLinkHandler> getTabs() throws ParsingException {
|
||||
return Arrays.asList(
|
||||
new ChannelTabHandler(getLinkHandler(), ChannelTabHandler.Tab.Playlists),
|
||||
new ChannelTabHandler(getLinkHandler(), ChannelTabHandler.Tab.Albums));
|
||||
new ListLinkHandler(getOriginalUrl(), getUrl(), getId(),
|
||||
Collections.singletonList(ChannelTabs.PLAYLISTS), ""),
|
||||
new ListLinkHandler(getOriginalUrl(), getUrl(), getId(),
|
||||
Collections.singletonList(ChannelTabs.ALBUMS), "")
|
||||
);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
|
|
@ -7,8 +7,8 @@ import org.schabi.newpipe.extractor.StreamingService;
|
|||
import org.schabi.newpipe.extractor.channel.ChannelTabExtractor;
|
||||
import org.schabi.newpipe.extractor.downloader.Downloader;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.services.soundcloud.SoundcloudParsingHelper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
@ -22,29 +22,19 @@ public class SoundcloudChannelTabExtractor extends ChannelTabExtractor {
|
|||
private static final String USERS_ENDPOINT = SOUNDCLOUD_API_V2_URL + "users/";
|
||||
|
||||
public SoundcloudChannelTabExtractor(final StreamingService service,
|
||||
final ChannelTabHandler linkHandler) {
|
||||
final ListLinkHandler linkHandler) {
|
||||
super(service, linkHandler);
|
||||
userId = getLinkHandler().getId();
|
||||
}
|
||||
|
||||
private String getEndpoint() {
|
||||
switch (getTab()) {
|
||||
case Playlists:
|
||||
case ChannelTabs.PLAYLISTS:
|
||||
return "/playlists_without_albums";
|
||||
case Albums:
|
||||
case ChannelTabs.ALBUMS:
|
||||
return "/albums";
|
||||
}
|
||||
throw new IllegalArgumentException("unsupported tab: " + getTab().name());
|
||||
}
|
||||
|
||||
String getUrlSuffix() {
|
||||
switch (getTab()) {
|
||||
case Playlists:
|
||||
return "/sets";
|
||||
case Albums:
|
||||
return "/albums";
|
||||
}
|
||||
throw new IllegalArgumentException("tab " + getTab().name() + " not supported");
|
||||
throw new IllegalArgumentException("unsupported tab: " + getTab());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -58,12 +48,6 @@ public class SoundcloudChannelTabExtractor extends ChannelTabExtractor {
|
|||
return userId;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getUrl() throws ParsingException {
|
||||
return super.getUrl() + getUrlSuffix();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public InfoItemsPage<InfoItem> getInitialPage() throws IOException, ExtractionException {
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package org.schabi.newpipe.extractor.services.soundcloud.linkHandler;
|
||||
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class SoundcloudChannelTabLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
private static final SoundcloudChannelTabLinkHandlerFactory INSTANCE
|
||||
= new SoundcloudChannelTabLinkHandlerFactory();
|
||||
|
||||
private SoundcloudChannelTabLinkHandlerFactory() {
|
||||
}
|
||||
|
||||
public static SoundcloudChannelTabLinkHandlerFactory getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private static String getUrlSuffix(final String tab) throws ParsingException {
|
||||
switch (tab) {
|
||||
case ChannelTabs.PLAYLISTS:
|
||||
return "/sets";
|
||||
case ChannelTabs.ALBUMS:
|
||||
return "/albums";
|
||||
}
|
||||
throw new ParsingException("tab " + tab + " not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(final String url) throws ParsingException {
|
||||
return SoundcloudChannelLinkHandlerFactory.getInstance().getId(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(final String id, final List<String> contentFilter, final String sortFilter)
|
||||
throws ParsingException {
|
||||
return SoundcloudChannelLinkHandlerFactory.getInstance().getUrl(id)
|
||||
+ getUrlSuffix(contentFilter.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onAcceptUrl(final String url) throws ParsingException {
|
||||
return SoundcloudChannelLinkHandlerFactory.getInstance().onAcceptUrl(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAvailableContentFilter() {
|
||||
return new String[] {
|
||||
ChannelTabs.PLAYLISTS,
|
||||
ChannelTabs.ALBUMS,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -483,7 +483,7 @@ public final class YoutubeParsingHelper {
|
|||
/**
|
||||
* @param playlistId the playlist id to parse
|
||||
* @return the {@link PlaylistInfo.PlaylistType} extracted from the playlistId (mix playlist
|
||||
* types included)
|
||||
* types included)
|
||||
* @throws ParsingException if the playlistId is null or empty, if the playlistId is not a mix,
|
||||
* if it is a mix but it's not based on a specific stream (this is the
|
||||
* case for channel or genre mixes)
|
||||
|
@ -516,7 +516,7 @@ public final class YoutubeParsingHelper {
|
|||
// 11 characters then it can't be a video id, hence we are dealing with a different
|
||||
// type of mix (e.g. genre mixes handled above, of the form RDGMEM{garbage})
|
||||
throw new ParsingException("Video id could not be determined from mix id: "
|
||||
+ playlistId);
|
||||
+ playlistId);
|
||||
}
|
||||
return playlistId.substring(2);
|
||||
|
||||
|
@ -529,7 +529,7 @@ public final class YoutubeParsingHelper {
|
|||
/**
|
||||
* @param playlistId the playlist id to parse
|
||||
* @return the {@link PlaylistInfo.PlaylistType} extracted from the playlistId (mix playlist
|
||||
* types included)
|
||||
* types included)
|
||||
* @throws ParsingException if the playlistId is null or empty
|
||||
*/
|
||||
@Nonnull
|
||||
|
@ -557,7 +557,7 @@ public final class YoutubeParsingHelper {
|
|||
/**
|
||||
* @param playlistUrl the playlist url to parse
|
||||
* @return the {@link PlaylistInfo.PlaylistType} extracted from the playlistUrl's list param
|
||||
* (mix playlist types included)
|
||||
* (mix playlist types included)
|
||||
* @throws ParsingException if the playlistUrl is malformed, if has no list param or if the list
|
||||
* param is empty
|
||||
*/
|
||||
|
@ -587,20 +587,20 @@ public final class YoutubeParsingHelper {
|
|||
}
|
||||
// @formatter:off
|
||||
final byte[] body = JsonWriter.string()
|
||||
.object()
|
||||
.object()
|
||||
.object("context")
|
||||
.object("client")
|
||||
.value("hl", "en-GB")
|
||||
.value("gl", "GB")
|
||||
.value("clientName", "WEB")
|
||||
.value("clientVersion", HARDCODED_CLIENT_VERSION)
|
||||
.end()
|
||||
.object("client")
|
||||
.value("hl", "en-GB")
|
||||
.value("gl", "GB")
|
||||
.value("clientName", "WEB")
|
||||
.value("clientVersion", HARDCODED_CLIENT_VERSION)
|
||||
.end()
|
||||
.object("user")
|
||||
.value("lockedSafetyMode", false)
|
||||
.value("lockedSafetyMode", false)
|
||||
.end()
|
||||
.value("fetchLiveState", true)
|
||||
.end()
|
||||
.end().done().getBytes(UTF_8);
|
||||
.end().done().getBytes(UTF_8);
|
||||
// @formatter:on
|
||||
|
||||
final Map<String, List<String>> headers = new HashMap<>();
|
||||
|
@ -611,7 +611,7 @@ public final class YoutubeParsingHelper {
|
|||
// This endpoint is fetched by the YouTube website to get the items of its main menu and is
|
||||
// pretty lightweight (around 30kB)
|
||||
final Response response = getDownloader().post(YOUTUBEI_V1_URL + "guide?key="
|
||||
+ HARDCODED_KEY + DISABLE_PRETTY_PRINT_PARAMETER, headers, body);
|
||||
+ HARDCODED_KEY + DISABLE_PRETTY_PRINT_PARAMETER, headers, body);
|
||||
final String responseBody = response.responseBody();
|
||||
final int responseCode = response.responseCode();
|
||||
|
||||
|
@ -688,14 +688,14 @@ public final class YoutubeParsingHelper {
|
|||
throw new ParsingException(
|
||||
// CHECKSTYLE:OFF
|
||||
"Could not extract YouTube WEB InnerTube API key from HTML search results page");
|
||||
// CHECKSTYLE:ON
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
|
||||
if (clientVersion == null) {
|
||||
throw new ParsingException(
|
||||
// CHECKSTYLE:OFF
|
||||
"Could not extract YouTube WEB InnerTube client version from HTML search results page");
|
||||
// CHECKSTYLE:ON
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
|
||||
keyAndVersionExtracted = true;
|
||||
|
@ -822,30 +822,30 @@ public final class YoutubeParsingHelper {
|
|||
|
||||
// @formatter:off
|
||||
final byte[] json = JsonWriter.string()
|
||||
.object()
|
||||
.object()
|
||||
.object("context")
|
||||
.object("client")
|
||||
.value("clientName", "WEB_REMIX")
|
||||
.value("clientVersion", HARDCODED_YOUTUBE_MUSIC_KEY[2])
|
||||
.value("hl", "en-GB")
|
||||
.value("gl", "GB")
|
||||
.array("experimentIds").end()
|
||||
.value("experimentsToken", "")
|
||||
.object("locationInfo").end()
|
||||
.object("musicAppInfo").end()
|
||||
.end()
|
||||
.object("capabilities").end()
|
||||
.object("request")
|
||||
.array("internalExperimentFlags").end()
|
||||
.object("sessionIndex").end()
|
||||
.end()
|
||||
.object("activePlayers").end()
|
||||
.object("user")
|
||||
.value("enableSafetyMode", false)
|
||||
.end()
|
||||
.object("client")
|
||||
.value("clientName", "WEB_REMIX")
|
||||
.value("clientVersion", HARDCODED_YOUTUBE_MUSIC_KEY[2])
|
||||
.value("hl", "en-GB")
|
||||
.value("gl", "GB")
|
||||
.array("experimentIds").end()
|
||||
.value("experimentsToken", "")
|
||||
.object("locationInfo").end()
|
||||
.object("musicAppInfo").end()
|
||||
.end()
|
||||
.object("capabilities").end()
|
||||
.object("request")
|
||||
.array("internalExperimentFlags").end()
|
||||
.object("sessionIndex").end()
|
||||
.end()
|
||||
.object("activePlayers").end()
|
||||
.object("user")
|
||||
.value("enableSafetyMode", false)
|
||||
.end()
|
||||
.end()
|
||||
.value("input", "")
|
||||
.end().done().getBytes(UTF_8);
|
||||
.end().done().getBytes(UTF_8);
|
||||
// @formatter:on
|
||||
|
||||
final Map<String, List<String>> headers = new HashMap<>();
|
||||
|
@ -882,10 +882,10 @@ public final class YoutubeParsingHelper {
|
|||
headers.put("Origin", singletonList("https://music.youtube.com"));
|
||||
headers.put("Referer", singletonList("https://music.youtube.com"));
|
||||
final String response = getDownloader().get(url, headers).responseBody();
|
||||
musicClientVersion = getStringResultFromRegexArray(response,
|
||||
INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1);
|
||||
musicKey = getStringResultFromRegexArray(response, INNERTUBE_API_KEY_REGEXES, 1);
|
||||
musicClientName = Parser.matchGroup1(INNERTUBE_CLIENT_NAME_REGEX, response);
|
||||
musicClientVersion = getStringResultFromRegexArray(response,
|
||||
INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1);
|
||||
musicKey = getStringResultFromRegexArray(response, INNERTUBE_API_KEY_REGEXES, 1);
|
||||
musicClientName = Parser.matchGroup1(INNERTUBE_CLIENT_NAME_REGEX, response);
|
||||
} catch (final Exception e) {
|
||||
final String url = "https://music.youtube.com/?ucbcb=1";
|
||||
final String html = getDownloader().get(url, getCookieHeader()).responseBody();
|
||||
|
@ -896,7 +896,7 @@ public final class YoutubeParsingHelper {
|
|||
musicClientName = Parser.matchGroup1(INNERTUBE_CLIENT_NAME_REGEX, html);
|
||||
}
|
||||
|
||||
youtubeMusicKey = new String[] {musicKey, musicClientName, musicClientVersion};
|
||||
youtubeMusicKey = new String[]{musicKey, musicClientName, musicClientVersion};
|
||||
return youtubeMusicKey;
|
||||
}
|
||||
|
||||
|
@ -1142,52 +1142,40 @@ public final class YoutubeParsingHelper {
|
|||
@Nonnull
|
||||
public static JsonBuilder<JsonObject> prepareDesktopJsonBuilder(
|
||||
@Nonnull final Localization localization,
|
||||
@Nonnull final ContentCountry contentCountry,
|
||||
@Nullable final String vData)
|
||||
@Nonnull final ContentCountry contentCountry)
|
||||
throws IOException, ExtractionException {
|
||||
// @formatter:off
|
||||
final JsonBuilder<JsonObject> builder = JsonObject.builder()
|
||||
.object("context")
|
||||
.object("client")
|
||||
.value("hl", localization.getLocalizationCode())
|
||||
.value("gl", contentCountry.getCountryCode())
|
||||
.value("clientName", "WEB")
|
||||
.value("clientVersion", getClientVersion())
|
||||
.value("originalUrl", "https://www.youtube.com")
|
||||
.value("platform", "DESKTOP");
|
||||
.object("client")
|
||||
.value("hl", localization.getLocalizationCode())
|
||||
.value("gl", contentCountry.getCountryCode())
|
||||
.value("clientName", "WEB")
|
||||
.value("clientVersion", getClientVersion())
|
||||
.value("originalUrl", "https://www.youtube.com")
|
||||
.value("platform", "DESKTOP");
|
||||
|
||||
// Use specified visitor data, otherwise fall back to the configured value
|
||||
if (vData != null) {
|
||||
builder.value("visitorData", vData);
|
||||
} else if (visitorData != null) {
|
||||
if (visitorData != null) {
|
||||
builder.value("visitorData", visitorData);
|
||||
}
|
||||
|
||||
builder.end()
|
||||
.object("request")
|
||||
.array("internalExperimentFlags")
|
||||
.end()
|
||||
.value("useSsl", true)
|
||||
.end()
|
||||
.object("user")
|
||||
// TO DO: provide a way to enable restricted mode with:
|
||||
// .value("enableSafetyMode", boolean)
|
||||
.value("lockedSafetyMode", false)
|
||||
.end()
|
||||
.object("request")
|
||||
.array("internalExperimentFlags")
|
||||
.end()
|
||||
.value("useSsl", true)
|
||||
.end()
|
||||
.object("user")
|
||||
// TO DO: provide a way to enable restricted mode with:
|
||||
// .value("enableSafetyMode", boolean)
|
||||
.value("lockedSafetyMode", false)
|
||||
.end()
|
||||
.end();
|
||||
// @formatter:on
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static JsonBuilder<JsonObject> prepareDesktopJsonBuilder(
|
||||
@Nonnull final Localization localization,
|
||||
@Nonnull final ContentCountry contentCountry)
|
||||
throws IOException, ExtractionException {
|
||||
return prepareDesktopJsonBuilder(localization, contentCountry, visitorData);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static JsonBuilder<JsonObject> prepareAndroidMobileJsonBuilder(
|
||||
@Nonnull final Localization localization,
|
||||
|
@ -1195,32 +1183,32 @@ public final class YoutubeParsingHelper {
|
|||
// @formatter:off
|
||||
return JsonObject.builder()
|
||||
.object("context")
|
||||
.object("client")
|
||||
.value("clientName", "ANDROID")
|
||||
.value("clientVersion", ANDROID_YOUTUBE_CLIENT_VERSION)
|
||||
.value("platform", "MOBILE")
|
||||
.value("osName", "Android")
|
||||
.value("osVersion", "12")
|
||||
/*
|
||||
A valid Android SDK version is required to be sure to get a valid player
|
||||
response
|
||||
If this parameter is not provided, the player response may be replaced by
|
||||
the one of a 5-minute video saying the message "The following content is
|
||||
not available on this app. Watch this content on the latest version on
|
||||
YouTube"
|
||||
See https://github.com/TeamNewPipe/NewPipe/issues/8713
|
||||
The Android SDK version corresponding to the Android version used in
|
||||
requests is sent
|
||||
*/
|
||||
.value("androidSdkVersion", 31)
|
||||
.value("hl", localization.getLocalizationCode())
|
||||
.value("gl", contentCountry.getCountryCode())
|
||||
.end()
|
||||
.object("user")
|
||||
// TO DO: provide a way to enable restricted mode with:
|
||||
// .value("enableSafetyMode", boolean)
|
||||
.value("lockedSafetyMode", false)
|
||||
.end()
|
||||
.object("client")
|
||||
.value("clientName", "ANDROID")
|
||||
.value("clientVersion", ANDROID_YOUTUBE_CLIENT_VERSION)
|
||||
.value("platform", "MOBILE")
|
||||
.value("osName", "Android")
|
||||
.value("osVersion", "12")
|
||||
/*
|
||||
A valid Android SDK version is required to be sure to get a valid player
|
||||
response
|
||||
If this parameter is not provided, the player response may be replaced by
|
||||
the one of a 5-minute video saying the message "The following content is
|
||||
not available on this app. Watch this content on the latest version on
|
||||
YouTube"
|
||||
See https://github.com/TeamNewPipe/NewPipe/issues/8713
|
||||
The Android SDK version corresponding to the Android version used in
|
||||
requests is sent
|
||||
*/
|
||||
.value("androidSdkVersion", 31)
|
||||
.value("hl", localization.getLocalizationCode())
|
||||
.value("gl", contentCountry.getCountryCode())
|
||||
.end()
|
||||
.object("user")
|
||||
// TO DO: provide a way to enable restricted mode with:
|
||||
// .value("enableSafetyMode", boolean)
|
||||
.value("lockedSafetyMode", false)
|
||||
.end()
|
||||
.end();
|
||||
// @formatter:on
|
||||
}
|
||||
|
@ -1232,27 +1220,27 @@ public final class YoutubeParsingHelper {
|
|||
// @formatter:off
|
||||
return JsonObject.builder()
|
||||
.object("context")
|
||||
.object("client")
|
||||
.value("clientName", "IOS")
|
||||
.value("clientVersion", IOS_YOUTUBE_CLIENT_VERSION)
|
||||
.value("deviceMake", "Apple")
|
||||
// Device model is required to get 60fps streams
|
||||
.value("deviceModel", IOS_DEVICE_MODEL)
|
||||
.value("platform", "MOBILE")
|
||||
.value("osName", "iOS")
|
||||
// The value of this field seems to use the following structure:
|
||||
// "iOS version.0.build version"
|
||||
// The build version corresponding to the iOS version used can be found on
|
||||
// https://www.theiphonewiki.com/wiki/Firmware/iPhone/15.x#iPhone_13
|
||||
.value("osVersion", "15.6.0.19G71")
|
||||
.value("hl", localization.getLocalizationCode())
|
||||
.value("gl", contentCountry.getCountryCode())
|
||||
.end()
|
||||
.object("user")
|
||||
// TO DO: provide a way to enable restricted mode with:
|
||||
// .value("enableSafetyMode", boolean)
|
||||
.value("lockedSafetyMode", false)
|
||||
.end()
|
||||
.object("client")
|
||||
.value("clientName", "IOS")
|
||||
.value("clientVersion", IOS_YOUTUBE_CLIENT_VERSION)
|
||||
.value("deviceMake", "Apple")
|
||||
// Device model is required to get 60fps streams
|
||||
.value("deviceModel", IOS_DEVICE_MODEL)
|
||||
.value("platform", "MOBILE")
|
||||
.value("osName", "iOS")
|
||||
// The value of this field seems to use the following structure:
|
||||
// "iOS version.0.build version"
|
||||
// The build version corresponding to the iOS version used can be found on
|
||||
// https://www.theiphonewiki.com/wiki/Firmware/iPhone/15.x#iPhone_13
|
||||
.value("osVersion", "15.6.0.19G71")
|
||||
.value("hl", localization.getLocalizationCode())
|
||||
.value("gl", contentCountry.getCountryCode())
|
||||
.end()
|
||||
.object("user")
|
||||
// TO DO: provide a way to enable restricted mode with:
|
||||
// .value("enableSafetyMode", boolean)
|
||||
.value("lockedSafetyMode", false)
|
||||
.end()
|
||||
.end();
|
||||
// @formatter:on
|
||||
}
|
||||
|
@ -1265,22 +1253,22 @@ public final class YoutubeParsingHelper {
|
|||
// @formatter:off
|
||||
return JsonObject.builder()
|
||||
.object("context")
|
||||
.object("client")
|
||||
.value("clientName", "TVHTML5_SIMPLY_EMBEDDED_PLAYER")
|
||||
.value("clientVersion", TVHTML5_SIMPLY_EMBED_CLIENT_VERSION)
|
||||
.value("clientScreen", "EMBED")
|
||||
.value("platform", "TV")
|
||||
.value("hl", localization.getLocalizationCode())
|
||||
.value("gl", contentCountry.getCountryCode())
|
||||
.end()
|
||||
.object("thirdParty")
|
||||
.value("embedUrl", "https://www.youtube.com/watch?v=" + videoId)
|
||||
.end()
|
||||
.object("user")
|
||||
// TO DO: provide a way to enable restricted mode with:
|
||||
// .value("enableSafetyMode", boolean)
|
||||
.value("lockedSafetyMode", false)
|
||||
.end()
|
||||
.object("client")
|
||||
.value("clientName", "TVHTML5_SIMPLY_EMBEDDED_PLAYER")
|
||||
.value("clientVersion", TVHTML5_SIMPLY_EMBED_CLIENT_VERSION)
|
||||
.value("clientScreen", "EMBED")
|
||||
.value("platform", "TV")
|
||||
.value("hl", localization.getLocalizationCode())
|
||||
.value("gl", contentCountry.getCountryCode())
|
||||
.end()
|
||||
.object("thirdParty")
|
||||
.value("embedUrl", "https://www.youtube.com/watch?v=" + videoId)
|
||||
.end()
|
||||
.object("user")
|
||||
// TO DO: provide a way to enable restricted mode with:
|
||||
// .value("enableSafetyMode", boolean)
|
||||
.value("lockedSafetyMode", false)
|
||||
.end()
|
||||
.end();
|
||||
// @formatter:on
|
||||
}
|
||||
|
@ -1297,19 +1285,19 @@ public final class YoutubeParsingHelper {
|
|||
return JsonWriter.string((isTvHtml5DesktopJsonBuilder
|
||||
? prepareTvHtml5EmbedJsonBuilder(localization, contentCountry, videoId)
|
||||
: prepareDesktopJsonBuilder(localization, contentCountry))
|
||||
.object("playbackContext")
|
||||
.object("contentPlaybackContext")
|
||||
.object("playbackContext")
|
||||
.object("contentPlaybackContext")
|
||||
// Signature timestamp from the JavaScript base player is needed to get
|
||||
// working obfuscated URLs
|
||||
.value("signatureTimestamp", sts)
|
||||
.value("referer", "https://www.youtube.com/watch?v=" + videoId)
|
||||
.end()
|
||||
.end()
|
||||
.value(CPN, contentPlaybackNonce)
|
||||
.value(VIDEO_ID, videoId)
|
||||
.value(CONTENT_CHECK_OK, true)
|
||||
.value(RACY_CHECK_OK, true)
|
||||
.done())
|
||||
.end()
|
||||
.end()
|
||||
.value(CPN, contentPlaybackNonce)
|
||||
.value(VIDEO_ID, videoId)
|
||||
.value(CONTENT_CHECK_OK, true)
|
||||
.value(RACY_CHECK_OK, true)
|
||||
.done())
|
||||
.getBytes(StandardCharsets.UTF_8);
|
||||
// @formatter:on
|
||||
}
|
||||
|
@ -1704,8 +1692,7 @@ public final class YoutubeParsingHelper {
|
|||
public static ChannelResponseData getChannelResponse(final String channelId,
|
||||
final String params,
|
||||
final Localization loc,
|
||||
final ContentCountry country,
|
||||
@Nullable final String vData)
|
||||
final ContentCountry country)
|
||||
throws ExtractionException, IOException {
|
||||
String id = channelId;
|
||||
JsonObject ajaxJson = null;
|
||||
|
@ -1713,7 +1700,7 @@ public final class YoutubeParsingHelper {
|
|||
int level = 0;
|
||||
while (level < 3) {
|
||||
final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder(
|
||||
loc, country, vData)
|
||||
loc, country)
|
||||
.value("browseId", id)
|
||||
.value("params", params) // Equal to videos
|
||||
.done())
|
||||
|
|
|
@ -7,7 +7,6 @@ import org.schabi.newpipe.extractor.comments.CommentsExtractor;
|
|||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.feed.FeedExtractor;
|
||||
import org.schabi.newpipe.extractor.kiosk.KioskList;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
|
@ -31,6 +30,7 @@ import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeSubscript
|
|||
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeSuggestionExtractor;
|
||||
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeTrendingExtractor;
|
||||
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelTabLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeCommentsLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubePlaylistLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeSearchQueryHandlerFactory;
|
||||
|
@ -90,6 +90,11 @@ public class YoutubeService extends StreamingService {
|
|||
return YoutubeChannelLinkHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getChannelTabLHFactory() {
|
||||
return YoutubeChannelTabLinkHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getPlaylistLHFactory() {
|
||||
return YoutubePlaylistLinkHandlerFactory.getInstance();
|
||||
|
@ -111,7 +116,7 @@ public class YoutubeService extends StreamingService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ChannelTabExtractor getChannelTabExtractor(final ChannelTabHandler linkHandler) {
|
||||
public ChannelTabExtractor getChannelTabExtractor(final ListLinkHandler linkHandler) {
|
||||
return new YoutubeChannelTabExtractor(this, linkHandler);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,11 +11,10 @@ import org.schabi.newpipe.extractor.downloader.Response;
|
|||
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.localization.TimeAgoParser;
|
||||
import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper;
|
||||
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YouTubeChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
||||
|
@ -27,6 +26,7 @@ import javax.annotation.Nullable;
|
|||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -69,7 +69,7 @@ import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
|||
public class YoutubeChannelExtractor extends ChannelExtractor {
|
||||
private JsonObject initialData;
|
||||
private JsonObject videoTab;
|
||||
private List<ChannelTabHandler> tabs;
|
||||
private List<ListLinkHandler> tabs;
|
||||
|
||||
/**
|
||||
* Some channels have response redirects and the only way to reliably get the id is by saving it
|
||||
|
@ -94,7 +94,7 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
|
|||
final String channelPath = super.getId();
|
||||
final String id = resolveChannelId(channelPath);
|
||||
final ChannelResponseData data = getChannelResponse(id, "EgZ2aWRlb3M%3D",
|
||||
getExtractorLocalization(), getExtractorContentCountry(), null);
|
||||
getExtractorLocalization(), getExtractorContentCountry());
|
||||
|
||||
initialData = data.responseJson;
|
||||
redirectedChannelId = data.channelId;
|
||||
|
@ -227,7 +227,7 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
|
|||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<ChannelTabHandler> getTabs() throws ParsingException {
|
||||
public List<ListLinkHandler> getTabs() throws ParsingException {
|
||||
getVideoTab();
|
||||
return tabs;
|
||||
}
|
||||
|
@ -393,8 +393,13 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
|
|||
final String visitorData = initialData.getObject("responseContext")
|
||||
.getString("visitorData");
|
||||
|
||||
final Consumer<ChannelTabHandler.Tab> addTab = tab ->
|
||||
tabs.add(new YouTubeChannelTabHandler(getLinkHandler(), tab, visitorData));
|
||||
final Consumer<String> addTab = tab -> {
|
||||
try {
|
||||
tabs.add(new ListLinkHandler(getOriginalUrl(), getUrl(), redirectedChannelId,
|
||||
Collections.singletonList(tab), ""));
|
||||
} catch (final ParsingException ignored) {
|
||||
}
|
||||
};
|
||||
|
||||
for (final Object tab : responseTabs) {
|
||||
if (((JsonObject) tab).has("tabRenderer")) {
|
||||
|
@ -411,16 +416,16 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
|
|||
foundVideoTab = tabRenderer;
|
||||
break;
|
||||
case "playlists":
|
||||
addTab.accept(ChannelTabHandler.Tab.Playlists);
|
||||
addTab.accept(ChannelTabs.PLAYLISTS);
|
||||
break;
|
||||
case "streams":
|
||||
addTab.accept(ChannelTabHandler.Tab.Livestreams);
|
||||
addTab.accept(ChannelTabs.LIVE);
|
||||
break;
|
||||
case "shorts":
|
||||
addTab.accept(ChannelTabHandler.Tab.Shorts);
|
||||
addTab.accept(ChannelTabs.SHORTS);
|
||||
break;
|
||||
case "channels":
|
||||
addTab.accept(ChannelTabHandler.Tab.Channels);
|
||||
addTab.accept(ChannelTabs.CHANNELS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,9 @@ import org.schabi.newpipe.extractor.downloader.Downloader;
|
|||
import org.schabi.newpipe.extractor.downloader.Response;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YouTubeChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelTabLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.utils.JsonUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
@ -22,6 +22,7 @@ import javax.annotation.Nullable;
|
|||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -45,47 +46,22 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
|
|||
private String redirectedChannelId;
|
||||
|
||||
public YoutubeChannelTabExtractor(final StreamingService service,
|
||||
final ChannelTabHandler linkHandler) {
|
||||
final ListLinkHandler linkHandler) {
|
||||
super(service, linkHandler);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String getParams() {
|
||||
private String getParams() throws ParsingException {
|
||||
switch (getTab()) {
|
||||
case Playlists:
|
||||
case ChannelTabs.PLAYLISTS:
|
||||
return "EglwbGF5bGlzdHPyBgQKAkIA";
|
||||
case Livestreams:
|
||||
case ChannelTabs.LIVE:
|
||||
return "EgdzdHJlYW1z8gYECgJ6AA%3D%3D";
|
||||
case Shorts:
|
||||
case ChannelTabs.SHORTS:
|
||||
return "EgZzaG9ydHPyBgUKA5oBAA%3D%3D";
|
||||
case Channels:
|
||||
case ChannelTabs.CHANNELS:
|
||||
return "EghjaGFubmVsc_IGBAoCUgA%3D";
|
||||
}
|
||||
throw new IllegalArgumentException("tab " + getTab().name() + " not supported");
|
||||
}
|
||||
|
||||
String getUrlSuffix() {
|
||||
switch (getTab()) {
|
||||
case Playlists:
|
||||
return "/playlists";
|
||||
case Livestreams:
|
||||
return "/streams";
|
||||
case Shorts:
|
||||
return "/shorts";
|
||||
case Channels:
|
||||
return "/channels";
|
||||
}
|
||||
throw new IllegalArgumentException("tab " + getTab().name() + " not supported");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getVisitorData() {
|
||||
final ChannelTabHandler tabHandler = getLinkHandler();
|
||||
if (tabHandler instanceof YouTubeChannelTabHandler) {
|
||||
return ((YouTubeChannelTabHandler) tabHandler).getVisitorData();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
throw new ParsingException("tab " + getTab() + " not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -94,8 +70,7 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
|
|||
final String params = getParams();
|
||||
final String id = resolveChannelId(super.getId());
|
||||
final ChannelResponseData data = getChannelResponse(id, params,
|
||||
getExtractorLocalization(), getExtractorContentCountry(),
|
||||
getVisitorData());
|
||||
getExtractorLocalization(), getExtractorContentCountry());
|
||||
|
||||
initialData = data.responseJson;
|
||||
redirectedChannelId = data.channelId;
|
||||
|
@ -105,8 +80,8 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
|
|||
@Override
|
||||
public String getUrl() throws ParsingException {
|
||||
try {
|
||||
return YoutubeChannelLinkHandlerFactory.getInstance().getUrl(
|
||||
"channel/" + getId() + getUrlSuffix());
|
||||
return YoutubeChannelTabLinkHandlerFactory.getInstance().getUrl("channel/" + getId(),
|
||||
Collections.singletonList(getTab()), "");
|
||||
} catch (final ParsingException e) {
|
||||
return super.getUrl();
|
||||
}
|
||||
|
@ -199,11 +174,13 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
|
|||
}
|
||||
|
||||
@Nullable
|
||||
private JsonObject getTabData() {
|
||||
private JsonObject getTabData() throws ParsingException {
|
||||
if (this.tabData != null) {
|
||||
return this.tabData;
|
||||
}
|
||||
|
||||
final String urlSuffix = YoutubeChannelTabLinkHandlerFactory.getUrlSuffix(getTab());
|
||||
|
||||
final JsonArray tabs = initialData.getObject("contents")
|
||||
.getObject("twoColumnBrowseResultsRenderer")
|
||||
.getArray("tabs");
|
||||
|
@ -213,7 +190,7 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
|
|||
if (((JsonObject) tab).has("tabRenderer")) {
|
||||
if (((JsonObject) tab).getObject("tabRenderer").getObject("endpoint")
|
||||
.getObject("commandMetadata").getObject("webCommandMetadata")
|
||||
.getString("url").endsWith(getUrlSuffix())) {
|
||||
.getString("url").endsWith(urlSuffix)) {
|
||||
foundTab = ((JsonObject) tab).getObject("tabRenderer");
|
||||
break;
|
||||
}
|
||||
|
@ -324,8 +301,7 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
|
|||
.getString("token");
|
||||
|
||||
final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder(getExtractorLocalization(),
|
||||
getExtractorContentCountry(),
|
||||
getVisitorData())
|
||||
getExtractorContentCountry())
|
||||
.value("continuation", continuation)
|
||||
.done())
|
||||
.getBytes(StandardCharsets.UTF_8);
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
package org.schabi.newpipe.extractor.services.youtube.linkHandler;
|
||||
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class YouTubeChannelTabHandler extends ChannelTabHandler {
|
||||
|
||||
/**
|
||||
* Since YouTube is currently A/B testing a new tab layout,
|
||||
* we need to store the visitor data cookie when fetching a channel and pass it to
|
||||
* YouTube when requesting channel tabs. Otherwise YouTube may not enable the A/B test
|
||||
* on subsequent requests and return empty tabs.
|
||||
* <p>
|
||||
* This may be removed when the new layout is made permanent.
|
||||
*/
|
||||
@Nullable
|
||||
private final String visitorData;
|
||||
|
||||
public YouTubeChannelTabHandler(final ListLinkHandler linkHandler, final Tab tab,
|
||||
@Nullable final String visitorData) {
|
||||
super(linkHandler, tab);
|
||||
this.visitorData = visitorData;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getVisitorData() {
|
||||
return visitorData;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package org.schabi.newpipe.extractor.services.youtube.linkHandler;
|
||||
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class YoutubeChannelTabLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
private static final YoutubeChannelTabLinkHandlerFactory INSTANCE =
|
||||
new YoutubeChannelTabLinkHandlerFactory();
|
||||
|
||||
private YoutubeChannelTabLinkHandlerFactory() {
|
||||
}
|
||||
|
||||
public static YoutubeChannelTabLinkHandlerFactory getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static String getUrlSuffix(final String tab) throws ParsingException {
|
||||
switch (tab) {
|
||||
case ChannelTabs.PLAYLISTS:
|
||||
return "/playlists";
|
||||
case ChannelTabs.LIVE:
|
||||
return "/streams";
|
||||
case ChannelTabs.SHORTS:
|
||||
return "/shorts";
|
||||
case ChannelTabs.CHANNELS:
|
||||
return "/channels";
|
||||
}
|
||||
throw new ParsingException("tab " + tab + " not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(final String id, final List<String> contentFilter, final String sortFilter)
|
||||
throws ParsingException {
|
||||
return "https://www.youtube.com/" + id + getUrlSuffix(contentFilter.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(final String url) throws ParsingException {
|
||||
return YoutubeChannelLinkHandlerFactory.getInstance().getId(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onAcceptUrl(final String url) throws ParsingException {
|
||||
try {
|
||||
getId(url);
|
||||
} catch (final ParsingException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAvailableContentFilter() {
|
||||
return new String[] {
|
||||
ChannelTabs.SHORTS,
|
||||
ChannelTabs.LIVE,
|
||||
ChannelTabs.CHANNELS,
|
||||
ChannelTabs.PLAYLISTS,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ public class BandcampChannelLinkHandlerFactoryTest {
|
|||
|
||||
@BeforeAll
|
||||
public static void setUp() {
|
||||
linkHandler = new BandcampChannelLinkHandlerFactory();
|
||||
linkHandler = BandcampChannelLinkHandlerFactory.getInstance();
|
||||
NewPipe.init(DownloaderTestImpl.getInstance());
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.schabi.newpipe.downloader.DownloaderTestImpl;
|
|||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampChannelTabExtractor;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -23,8 +23,7 @@ public class BandcampChannelTabExtractorTest {
|
|||
public static void setUp() throws IOException, ExtractionException {
|
||||
NewPipe.init(DownloaderTestImpl.getInstance());
|
||||
extractor = (BandcampChannelTabExtractor) Bandcamp
|
||||
.getChannelTabExtractorFromUrl("https://toupie.bandcamp.com/releases",
|
||||
ChannelTabHandler.Tab.Albums);
|
||||
.getChannelTabExtractorFromId("2450875064", ChannelTabs.ALBUMS);
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
|
@ -35,7 +34,7 @@ public class BandcampChannelTabExtractorTest {
|
|||
|
||||
@Test
|
||||
public void testTab() {
|
||||
assertEquals(ChannelTabHandler.Tab.Albums, extractor.getTab());
|
||||
assertEquals(ChannelTabs.ALBUMS, extractor.getTab());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.schabi.newpipe.downloader.DownloaderTestImpl;
|
|||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeAccountTabExtractor;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeChannelTabExtractor;
|
||||
|
||||
|
@ -24,8 +24,8 @@ public class PeertubeChannelTabExtractorTest {
|
|||
public static void setUp() throws IOException, ExtractionException {
|
||||
NewPipe.init(DownloaderTestImpl.getInstance());
|
||||
extractor = (PeertubeChannelTabExtractor) PeerTube
|
||||
.getChannelTabExtractorFromUrl("https://framatube.org/video-channels/lqdn_channel@video.lqdn.fr/videos",
|
||||
ChannelTabHandler.Tab.Playlists);
|
||||
.getChannelTabExtractorFromId("video-channels/lqdn_channel@video.lqdn.fr",
|
||||
ChannelTabs.PLAYLISTS, "https://framatube.org");
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ public class PeertubeChannelTabExtractorTest {
|
|||
|
||||
@Test
|
||||
public void testTab() {
|
||||
assertEquals(ChannelTabHandler.Tab.Playlists, extractor.getTab());
|
||||
assertEquals(ChannelTabs.PLAYLISTS, extractor.getTab());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -62,8 +62,8 @@ public class PeertubeChannelTabExtractorTest {
|
|||
public static void setUp() throws IOException, ExtractionException {
|
||||
NewPipe.init(DownloaderTestImpl.getInstance());
|
||||
extractor = (PeertubeAccountTabExtractor) PeerTube
|
||||
.getChannelTabExtractorFromUrl("https://framatube.org/accounts/framasoft",
|
||||
ChannelTabHandler.Tab.Channels);
|
||||
.getChannelTabExtractorFromId("accounts/framasoft",
|
||||
ChannelTabs.CHANNELS, "https://framatube.org");
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ public class PeertubeChannelTabExtractorTest {
|
|||
|
||||
@Test
|
||||
public void testTab() {
|
||||
assertEquals(ChannelTabHandler.Tab.Channels, extractor.getTab());
|
||||
assertEquals(ChannelTabs.CHANNELS, extractor.getTab());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.schabi.newpipe.downloader.DownloaderTestImpl;
|
|||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudChannelTabExtractor;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -24,8 +24,7 @@ public class SoundcloudChannelTabExtractorTest {
|
|||
public static void setUp() throws IOException, ExtractionException {
|
||||
NewPipe.init(DownloaderTestImpl.getInstance());
|
||||
extractor = (SoundcloudChannelTabExtractor) SoundCloud
|
||||
.getChannelTabExtractorFromUrl("https://soundcloud.com/trackaholic",
|
||||
ChannelTabHandler.Tab.Playlists);
|
||||
.getChannelTabExtractorFromId("323371733", ChannelTabs.PLAYLISTS);
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
|
@ -36,7 +35,7 @@ public class SoundcloudChannelTabExtractorTest {
|
|||
|
||||
@Test
|
||||
public void testTab() {
|
||||
assertEquals(ChannelTabHandler.Tab.Playlists, extractor.getTab());
|
||||
assertEquals(ChannelTabs.PLAYLISTS, extractor.getTab());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -67,8 +66,7 @@ public class SoundcloudChannelTabExtractorTest {
|
|||
public static void setUp() throws IOException, ExtractionException {
|
||||
NewPipe.init(DownloaderTestImpl.getInstance());
|
||||
extractor = (SoundcloudChannelTabExtractor) SoundCloud
|
||||
.getChannelTabExtractorFromUrl("https://soundcloud.com/bigsean-1",
|
||||
ChannelTabHandler.Tab.Albums);
|
||||
.getChannelTabExtractorFromId("4803918", ChannelTabs.ALBUMS);
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
|
@ -79,7 +77,7 @@ public class SoundcloudChannelTabExtractorTest {
|
|||
|
||||
@Test
|
||||
public void testTab() {
|
||||
assertEquals(ChannelTabHandler.Tab.Albums, extractor.getTab());
|
||||
assertEquals(ChannelTabs.ALBUMS, extractor.getTab());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.schabi.newpipe.downloader.DownloaderFactory;
|
|||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeChannelTabExtractor;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -27,7 +27,7 @@ public class YouTubeChannelTabExtractorTest {
|
|||
YoutubeTestsUtils.ensureStateless();
|
||||
NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "playlists"));
|
||||
extractor = (YoutubeChannelTabExtractor) YouTube.getChannelTabExtractorFromId(
|
||||
"UC2DjFE7Xf11URZqWBigcVOQ", ChannelTabHandler.Tab.Playlists);
|
||||
"UC2DjFE7Xf11URZqWBigcVOQ", ChannelTabs.PLAYLISTS);
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ public class YouTubeChannelTabExtractorTest {
|
|||
|
||||
@Test
|
||||
public void testTab() {
|
||||
assertEquals(ChannelTabHandler.Tab.Playlists, extractor.getTab());
|
||||
assertEquals(ChannelTabs.PLAYLISTS, extractor.getTab());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -69,7 +69,7 @@ public class YouTubeChannelTabExtractorTest {
|
|||
public static void setUp() throws IOException, ExtractionException {
|
||||
YoutubeTestsUtils.ensureStateless();
|
||||
NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "channels"));
|
||||
extractor = (YoutubeChannelTabExtractor) YouTube.getChannelTabExtractorFromId("UC2DjFE7Xf11URZqWBigcVOQ", ChannelTabHandler.Tab.Channels);
|
||||
extractor = (YoutubeChannelTabExtractor) YouTube.getChannelTabExtractorFromId("UC2DjFE7Xf11URZqWBigcVOQ", ChannelTabs.CHANNELS);
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ public class YouTubeChannelTabExtractorTest {
|
|||
|
||||
@Test
|
||||
public void testTab() {
|
||||
assertEquals(ChannelTabHandler.Tab.Channels, extractor.getTab());
|
||||
assertEquals(ChannelTabs.CHANNELS, extractor.getTab());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -112,7 +112,7 @@ public class YouTubeChannelTabExtractorTest {
|
|||
YoutubeTestsUtils.ensureStateless();
|
||||
YoutubeParsingHelper.setVisitorData(YoutubeTestsUtils.VISITOR_DATA_NEW_CHANNEL_LAYOUT);
|
||||
NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "livestreams"));
|
||||
extractor = (YoutubeChannelTabExtractor) YouTube.getChannelTabExtractorFromId("UCR-DXc1voovS8nhAvccRZhg", ChannelTabHandler.Tab.Livestreams);
|
||||
extractor = (YoutubeChannelTabExtractor) YouTube.getChannelTabExtractorFromId("UCR-DXc1voovS8nhAvccRZhg", ChannelTabs.LIVE);
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,7 @@ public class YouTubeChannelTabExtractorTest {
|
|||
|
||||
@Test
|
||||
public void testTab() {
|
||||
assertEquals(ChannelTabHandler.Tab.Livestreams, extractor.getTab());
|
||||
assertEquals(ChannelTabs.LIVE, extractor.getTab());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -133,7 +133,7 @@ public class YouTubeChannelTabExtractorTest {
|
|||
|
||||
@Test
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ/live", extractor.getUrl());
|
||||
assertEquals("https://www.youtube.com/channel/UCR-DXc1voovS8nhAvccRZhg/streams", extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -155,7 +155,7 @@ public class YouTubeChannelTabExtractorTest {
|
|||
YoutubeTestsUtils.ensureStateless();
|
||||
YoutubeParsingHelper.setVisitorData(YoutubeTestsUtils.VISITOR_DATA_NEW_CHANNEL_LAYOUT);
|
||||
NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "shorts"));
|
||||
extractor = (YoutubeChannelTabExtractor) YouTube.getChannelTabExtractorFromId("UCh8gHdtzO2tXd593_bjErWg", ChannelTabHandler.Tab.Shorts);
|
||||
extractor = (YoutubeChannelTabExtractor) YouTube.getChannelTabExtractorFromId("UCh8gHdtzO2tXd593_bjErWg", ChannelTabs.SHORTS);
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,7 @@ public class YouTubeChannelTabExtractorTest {
|
|||
|
||||
@Test
|
||||
public void testTab() {
|
||||
assertEquals(ChannelTabHandler.Tab.Shorts, extractor.getTab());
|
||||
assertEquals(ChannelTabs.SHORTS, extractor.getTab());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -12,7 +12,7 @@ import org.schabi.newpipe.extractor.exceptions.AccountTerminatedException;
|
|||
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.services.BaseChannelExtractorTest;
|
||||
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeChannelExtractor;
|
||||
|
||||
|
@ -240,9 +240,10 @@ public class YoutubeChannelExtractorTest {
|
|||
|
||||
@Test
|
||||
public void testTabs() throws Exception {
|
||||
Set<ChannelTabHandler.Tab> tabs = extractor.getTabs().stream().map(ChannelTabHandler::getTab).collect(Collectors.toSet());
|
||||
assertTrue(tabs.contains(ChannelTabHandler.Tab.Playlists));
|
||||
assertTrue(tabs.contains(ChannelTabHandler.Tab.Channels));
|
||||
Set<String> tabs = extractor.getTabs().stream()
|
||||
.map(linkHandler -> linkHandler.getContentFilters().get(0)).collect(Collectors.toSet());
|
||||
assertTrue(tabs.contains(ChannelTabs.PLAYLISTS));
|
||||
assertTrue(tabs.contains(ChannelTabs.CHANNELS));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -342,9 +343,10 @@ public class YoutubeChannelExtractorTest {
|
|||
|
||||
@Test
|
||||
public void testTabs() throws Exception {
|
||||
Set<ChannelTabHandler.Tab> tabs = extractor.getTabs().stream().map(ChannelTabHandler::getTab).collect(Collectors.toSet());
|
||||
assertTrue(tabs.contains(ChannelTabHandler.Tab.Playlists));
|
||||
assertTrue(tabs.contains(ChannelTabHandler.Tab.Channels));
|
||||
Set<String> tabs = extractor.getTabs().stream()
|
||||
.map(linkHandler -> linkHandler.getContentFilters().get(0)).collect(Collectors.toSet());
|
||||
assertTrue(tabs.contains(ChannelTabs.PLAYLISTS));
|
||||
assertTrue(tabs.contains(ChannelTabs.CHANNELS));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -446,9 +448,10 @@ public class YoutubeChannelExtractorTest {
|
|||
|
||||
@Test
|
||||
public void testTabs() throws Exception {
|
||||
Set<ChannelTabHandler.Tab> tabs = extractor.getTabs().stream().map(ChannelTabHandler::getTab).collect(Collectors.toSet());
|
||||
assertTrue(tabs.contains(ChannelTabHandler.Tab.Playlists));
|
||||
assertTrue(tabs.contains(ChannelTabHandler.Tab.Channels));
|
||||
Set<String> tabs = extractor.getTabs().stream()
|
||||
.map(linkHandler -> linkHandler.getContentFilters().get(0)).collect(Collectors.toSet());
|
||||
assertTrue(tabs.contains(ChannelTabs.PLAYLISTS));
|
||||
assertTrue(tabs.contains(ChannelTabs.CHANNELS));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -567,9 +570,10 @@ public class YoutubeChannelExtractorTest {
|
|||
|
||||
@Test
|
||||
public void testTabs() throws Exception {
|
||||
Set<ChannelTabHandler.Tab> tabs = extractor.getTabs().stream().map(ChannelTabHandler::getTab).collect(Collectors.toSet());
|
||||
assertTrue(tabs.contains(ChannelTabHandler.Tab.Playlists));
|
||||
assertTrue(tabs.contains(ChannelTabHandler.Tab.Channels));
|
||||
Set<String> tabs = extractor.getTabs().stream()
|
||||
.map(linkHandler -> linkHandler.getContentFilters().get(0)).collect(Collectors.toSet());
|
||||
assertTrue(tabs.contains(ChannelTabs.PLAYLISTS));
|
||||
assertTrue(tabs.contains(ChannelTabs.CHANNELS));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -674,9 +678,10 @@ public class YoutubeChannelExtractorTest {
|
|||
|
||||
@Test
|
||||
public void testTabs() throws Exception {
|
||||
Set<ChannelTabHandler.Tab> tabs = extractor.getTabs().stream().map(ChannelTabHandler::getTab).collect(Collectors.toSet());
|
||||
assertTrue(tabs.contains(ChannelTabHandler.Tab.Playlists));
|
||||
assertTrue(tabs.contains(ChannelTabHandler.Tab.Channels));
|
||||
Set<String> tabs = extractor.getTabs().stream()
|
||||
.map(linkHandler -> linkHandler.getContentFilters().get(0)).collect(Collectors.toSet());
|
||||
assertTrue(tabs.contains(ChannelTabs.PLAYLISTS));
|
||||
assertTrue(tabs.contains(ChannelTabs.CHANNELS));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -737,7 +742,7 @@ public class YoutubeChannelExtractorTest {
|
|||
/**
|
||||
* Test the extraction of the new channel tabs
|
||||
*/
|
||||
public static class ChannelTabs {
|
||||
public static class ChannelWithTabs {
|
||||
private static YoutubeChannelExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
|
@ -781,11 +786,12 @@ public class YoutubeChannelExtractorTest {
|
|||
|
||||
@Test
|
||||
public void testTabs() throws Exception {
|
||||
Set<ChannelTabHandler.Tab> tabs = extractor.getTabs().stream().map(ChannelTabHandler::getTab).collect(Collectors.toSet());
|
||||
assertTrue(tabs.contains(ChannelTabHandler.Tab.Shorts));
|
||||
assertTrue(tabs.contains(ChannelTabHandler.Tab.Livestreams));
|
||||
assertTrue(tabs.contains(ChannelTabHandler.Tab.Playlists));
|
||||
assertTrue(tabs.contains(ChannelTabHandler.Tab.Channels));
|
||||
Set<String> tabs = extractor.getTabs().stream()
|
||||
.map(linkHandler -> linkHandler.getContentFilters().get(0)).collect(Collectors.toSet());
|
||||
assertTrue(tabs.contains(ChannelTabs.SHORTS));
|
||||
assertTrue(tabs.contains(ChannelTabs.LIVE));
|
||||
assertTrue(tabs.contains(ChannelTabs.PLAYLISTS));
|
||||
assertTrue(tabs.contains(ChannelTabs.CHANNELS));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue