From 356a888d6c747a18d595dd7c060f86bbaf71924b Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Thu, 29 Jun 2023 17:34:31 +0200 Subject: [PATCH] Add structure of channel tabs This commit introduces the following breaking changes: - Three new classes have been added: - ChannelTabExtractor, class extending ListExtractor, which extracts InfoItems from a channel tab; - ChannelTabInfo extending ListInfo, which extracts InfoItems from a ChannelTabExtractor and returns them as a ChannelTabInfo; - ChannelTabs, an immutable class containing all supported channel tabs. - StreamingService implementations must implement new methods returning a channel tab LinkHandlerFactory (getChannelTabsLHFactory) and a ChannelTabExtractor (getChannelTabExtractor); - ChannelExtractor inherits Extractor instead of ListExtractor and ChannelInfo inherits Info instead of ListInfo; - ChannelExtractor and ChannelInfo have now getters and/or setters of tabs. Co-authored-by: ThetaDev Co-authored-by: Stypox --- .../newpipe/extractor/StreamingService.java | 32 +++++++++ .../extractor/channel/ChannelExtractor.java | 13 ++-- .../extractor/channel/ChannelInfo.java | 52 +++++++------- .../channel/tabs/ChannelTabExtractor.java | 25 +++++++ .../channel/tabs/ChannelTabInfo.java | 70 +++++++++++++++++++ .../extractor/channel/tabs/ChannelTabs.java | 17 +++++ 6 files changed, 180 insertions(+), 29 deletions(-) create mode 100644 extractor/src/main/java/org/schabi/newpipe/extractor/channel/tabs/ChannelTabExtractor.java create mode 100644 extractor/src/main/java/org/schabi/newpipe/extractor/channel/tabs/ChannelTabInfo.java create mode 100644 extractor/src/main/java/org/schabi/newpipe/extractor/channel/tabs/ChannelTabs.java diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/StreamingService.java b/extractor/src/main/java/org/schabi/newpipe/extractor/StreamingService.java index 94b8ba2d9..9b4b9a0f3 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/StreamingService.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/StreamingService.java @@ -1,6 +1,7 @@ package org.schabi.newpipe.extractor; import org.schabi.newpipe.extractor.channel.ChannelExtractor; +import org.schabi.newpipe.extractor.channel.tabs.ChannelTabExtractor; import org.schabi.newpipe.extractor.comments.CommentsExtractor; import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; @@ -140,6 +141,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. @@ -204,6 +213,15 @@ public abstract class StreamingService { public abstract ChannelExtractor getChannelExtractor(ListLinkHandler linkHandler) throws ExtractionException; + /** + * 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; + /** * Must crete a new instance of a PlaylistExtractor implementation. * @param linkHandler is pointing to the playlist which should be handled by this new instance. @@ -262,6 +280,20 @@ public abstract class StreamingService { return getChannelExtractor(getChannelLHFactory().fromUrl(url)); } + public ChannelTabExtractor getChannelTabExtractorFromId(final String id, final String tab) + throws ExtractionException { + return getChannelTabExtractor(getChannelTabLHFactory().fromQuery( + id, Collections.singletonList(tab), "")); + } + + public ChannelTabExtractor getChannelTabExtractorFromIdAndBaseUrl(final String id, + final String tab, + final String baseUrl) + throws ExtractionException { + return getChannelTabExtractor(getChannelTabLHFactory().fromQuery( + id, Collections.singletonList(tab), "", baseUrl)); + } + public PlaylistExtractor getPlaylistExtractor(final String url) throws ExtractionException { return getPlaylistExtractor(getPlaylistLHFactory().fromUrl(url)); } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/channel/ChannelExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/channel/ChannelExtractor.java index a04541124..ee4d77738 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/channel/ChannelExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/channel/ChannelExtractor.java @@ -1,10 +1,12 @@ package org.schabi.newpipe.extractor.channel; -import org.schabi.newpipe.extractor.ListExtractor; +import org.schabi.newpipe.extractor.Extractor; import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; -import org.schabi.newpipe.extractor.stream.StreamInfoItem; + +import javax.annotation.Nonnull; +import java.util.List; /* * Created by Christian Schabesberger on 25.07.16. @@ -26,11 +28,11 @@ import org.schabi.newpipe.extractor.stream.StreamInfoItem; * along with NewPipe. If not, see . */ -public abstract class ChannelExtractor extends ListExtractor { +public abstract class ChannelExtractor extends Extractor { public static final long UNKNOWN_SUBSCRIBER_COUNT = -1; - public ChannelExtractor(final StreamingService service, final ListLinkHandler linkHandler) { + protected ChannelExtractor(final StreamingService service, final ListLinkHandler linkHandler) { super(service, linkHandler); } @@ -43,5 +45,6 @@ public abstract class ChannelExtractor extends ListExtractor { public abstract String getParentChannelUrl() throws ParsingException; public abstract String getParentChannelAvatarUrl() throws ParsingException; public abstract boolean isVerified() throws ParsingException; - + @Nonnull + public abstract List getTabs() throws ParsingException; } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfo.java b/extractor/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfo.java index 7e82ba4d7..db4d65221 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfo.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfo.java @@ -1,16 +1,15 @@ package org.schabi.newpipe.extractor.channel; -import org.schabi.newpipe.extractor.ListExtractor.InfoItemsPage; -import org.schabi.newpipe.extractor.ListInfo; +import org.schabi.newpipe.extractor.Info; 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.ListLinkHandler; -import org.schabi.newpipe.extractor.stream.StreamInfoItem; -import org.schabi.newpipe.extractor.utils.ExtractorHelper; import java.io.IOException; +import java.util.List; + +import javax.annotation.Nonnull; /* * Created by Christian Schabesberger on 31.07.16. @@ -32,16 +31,14 @@ import java.io.IOException; * along with NewPipe. If not, see . */ -public class ChannelInfo extends ListInfo { +public class ChannelInfo extends Info { public ChannelInfo(final int serviceId, final String id, final String url, final String originalUrl, - final String name, - final ListLinkHandler listLinkHandler) { - super(serviceId, id, url, originalUrl, name, listLinkHandler.getContentFilters(), - listLinkHandler.getSortFilter()); + final String name) { + super(serviceId, id, url, originalUrl, name); } public static ChannelInfo getInfo(final String url) throws IOException, ExtractionException { @@ -55,13 +52,6 @@ public class ChannelInfo extends ListInfo { return getInfo(extractor); } - public static InfoItemsPage getMoreItems(final StreamingService service, - final String url, - final Page page) - throws IOException, ExtractionException { - return service.getChannelExtractor(url).getPage(page); - } - public static ChannelInfo getInfo(final ChannelExtractor extractor) throws IOException, ExtractionException { @@ -71,35 +61,32 @@ public class ChannelInfo extends ListInfo { final String originalUrl = extractor.getOriginalUrl(); final String name = extractor.getName(); - final ChannelInfo info = - new ChannelInfo(serviceId, id, url, originalUrl, name, extractor.getLinkHandler()); + final ChannelInfo info = new ChannelInfo(serviceId, id, url, originalUrl, name); try { info.setAvatarUrl(extractor.getAvatarUrl()); } catch (final Exception e) { info.addError(e); } + try { info.setBannerUrl(extractor.getBannerUrl()); } catch (final Exception e) { info.addError(e); } + try { info.setFeedUrl(extractor.getFeedUrl()); } catch (final Exception e) { info.addError(e); } - final InfoItemsPage itemsPage = - ExtractorHelper.getItemsPageOrLogError(info, extractor); - info.setRelatedItems(itemsPage.getItems()); - info.setNextPage(itemsPage.getNextPage()); - try { info.setSubscriberCount(extractor.getSubscriberCount()); } catch (final Exception e) { info.addError(e); } + try { info.setDescription(extractor.getDescription()); } catch (final Exception e) { @@ -130,6 +117,12 @@ public class ChannelInfo extends ListInfo { info.addError(e); } + try { + info.setTabs(extractor.getTabs()); + } catch (final Exception e) { + info.addError(e); + } + return info; } @@ -144,6 +137,8 @@ public class ChannelInfo extends ListInfo { private String[] donationLinks; private boolean verified; + private List tabs = List.of(); + public String getParentChannelName() { return parentChannelName; } @@ -223,4 +218,13 @@ public class ChannelInfo extends ListInfo { public void setVerified(final boolean verified) { this.verified = verified; } + + @Nonnull + public List getTabs() { + return tabs; + } + + public void setTabs(@Nonnull final List tabs) { + this.tabs = tabs; + } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/channel/tabs/ChannelTabExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/channel/tabs/ChannelTabExtractor.java new file mode 100644 index 000000000..79b6d2630 --- /dev/null +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/channel/tabs/ChannelTabExtractor.java @@ -0,0 +1,25 @@ +package org.schabi.newpipe.extractor.channel.tabs; + +import org.schabi.newpipe.extractor.InfoItem; +import org.schabi.newpipe.extractor.ListExtractor; +import org.schabi.newpipe.extractor.StreamingService; +import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; + +import javax.annotation.Nonnull; + +/** + * A {@link ListExtractor} of {@link InfoItem}s for tabs of channels. + */ +public abstract class ChannelTabExtractor extends ListExtractor { + + protected ChannelTabExtractor(@Nonnull final StreamingService service, + @Nonnull final ListLinkHandler linkHandler) { + super(service, linkHandler); + } + + @Nonnull + @Override + public String getName() { + return getLinkHandler().getContentFilters().get(0); + } +} diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/channel/tabs/ChannelTabInfo.java b/extractor/src/main/java/org/schabi/newpipe/extractor/channel/tabs/ChannelTabInfo.java new file mode 100644 index 000000000..8bc9fbfa7 --- /dev/null +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/channel/tabs/ChannelTabInfo.java @@ -0,0 +1,70 @@ +package org.schabi.newpipe.extractor.channel.tabs; + +import org.schabi.newpipe.extractor.InfoItem; +import org.schabi.newpipe.extractor.ListExtractor; +import org.schabi.newpipe.extractor.ListInfo; +import org.schabi.newpipe.extractor.Page; +import org.schabi.newpipe.extractor.StreamingService; +import org.schabi.newpipe.extractor.channel.ChannelInfo; +import org.schabi.newpipe.extractor.exceptions.ExtractionException; +import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; +import org.schabi.newpipe.extractor.utils.ExtractorHelper; + +import javax.annotation.Nonnull; +import java.io.IOException; + +public class ChannelTabInfo extends ListInfo { + + public ChannelTabInfo(final int serviceId, + @Nonnull final ListLinkHandler linkHandler) { + super(serviceId, linkHandler, linkHandler.getContentFilters().get(0)); + } + + /** + * Get a {@link ChannelTabInfo} instance from the given service and tab handler. + * + * @param service streaming service + * @param linkHandler Channel tab handler (from {@link ChannelInfo}) + * @return the extracted {@link ChannelTabInfo} + */ + @Nonnull + public static ChannelTabInfo getInfo(@Nonnull final StreamingService service, + @Nonnull final ListLinkHandler linkHandler) + throws ExtractionException, IOException { + final ChannelTabExtractor extractor = service.getChannelTabExtractor(linkHandler); + extractor.fetchPage(); + return getInfo(extractor); + } + + /** + * Get a {@link ChannelTabInfo} instance from a {@link ChannelTabExtractor}. + * + * @param extractor an extractor where {@code fetchPage()} was already got called on + * @return the extracted {@link ChannelTabInfo} + */ + @Nonnull + public static ChannelTabInfo getInfo(@Nonnull final ChannelTabExtractor extractor) { + final ChannelTabInfo info = + new ChannelTabInfo(extractor.getServiceId(), extractor.getLinkHandler()); + + try { + info.setOriginalUrl(extractor.getOriginalUrl()); + } catch (final Exception e) { + info.addError(e); + } + + final ListExtractor.InfoItemsPage page + = ExtractorHelper.getItemsPageOrLogError(info, extractor); + info.setRelatedItems(page.getItems()); + info.setNextPage(page.getNextPage()); + + return info; + } + + public static ListExtractor.InfoItemsPage getMoreItems( + @Nonnull final StreamingService service, + @Nonnull final ListLinkHandler linkHandler, + @Nonnull final Page page) throws ExtractionException, IOException { + return service.getChannelTabExtractor(linkHandler).getPage(page); + } +} diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/channel/tabs/ChannelTabs.java b/extractor/src/main/java/org/schabi/newpipe/extractor/channel/tabs/ChannelTabs.java new file mode 100644 index 000000000..ae3b2661e --- /dev/null +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/channel/tabs/ChannelTabs.java @@ -0,0 +1,17 @@ +package org.schabi.newpipe.extractor.channel.tabs; + +/** + * Constants of channel tabs supported by the extractor. + */ +public final class ChannelTabs { + public static final String VIDEOS = "videos"; + public static final String TRACKS = "tracks"; + public static final String SHORTS = "shorts"; + public static final String LIVESTREAMS = "livestreams"; + public static final String CHANNELS = "channels"; + public static final String PLAYLISTS = "playlists"; + public static final String ALBUMS = "albums"; + + private ChannelTabs() { + } +}