Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for channel tabs and channel tags #1082

Merged
merged 19 commits into from
Aug 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
356a888
Add structure of channel tabs
AudricV Jun 29, 2023
946eb9b
Add structure of channel tags
AudricV Jun 29, 2023
76fb9dc
Add UnsupportedOperationException to exceptions which can be thrown b…
AudricV Jun 29, 2023
de823a6
Add an UnsupportedTabException exception class
AudricV Jun 29, 2023
652c2c8
Add a ListLinkHandler which can be used to be returned from ChannelIn…
AudricV Jun 29, 2023
1e8474b
[PeerTube] Add tabs support for accounts and video channels
AudricV Jun 29, 2023
6f7d1f0
[Bandcamp] Add tabs support for artists
AudricV Jun 29, 2023
d4bfe79
[SoundCloud] Add tabs support for users
AudricV Jun 29, 2023
4586067
Add utility method to parse textual durations using TimeAgoParser's p…
AudricV Jul 14, 2023
7366eab
[YouTube] Add support for channel tabs and tags and age-restricted ch…
AudricV Jul 14, 2023
c70a0e3
Add a test for textual durations parsing using TimeAgoParser's patterns
Theta-Dev Jul 14, 2023
18846ba
Add tabs and tags methods in tests interfaces and annotate all method…
AudricV Jul 14, 2023
e0ba29c
Add utility method to assert that given channel tabs are in the ones …
AudricV Jul 14, 2023
8baec04
[Bandcamp] Implement link handlers and channels tabs and tags changes…
AudricV Jul 16, 2023
d3801dd
[MediaCCC] Implement link handlers and channels tabs and tags changes…
AudricV Jul 16, 2023
0ee2072
[PeerTube] Implement link handlers and channels tabs and tags changes…
AudricV Jul 16, 2023
eaf2600
[SoundCloud] Implement link handlers and channels tabs and tags chang…
AudricV Jul 16, 2023
684101c
[YouTube] Implement age-restricted channels support, link handlers an…
AudricV Jul 17, 2023
e7d6409
[YouTube] Update channel mocks and add channel tabs mocks
AudricV Jul 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -140,6 +141,14 @@ public String toString() {
*/
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.
Expand Down Expand Up @@ -204,6 +213,15 @@ public FeedExtractor getFeedExtractor(final String url) throws ExtractionExcepti
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.
Expand Down Expand Up @@ -262,6 +280,20 @@ public ChannelExtractor getChannelExtractor(final String url) throws ExtractionE
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));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -26,11 +28,11 @@
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/

public abstract class ChannelExtractor extends ListExtractor<StreamInfoItem> {
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);
}

Expand All @@ -43,5 +45,10 @@ public ChannelExtractor(final StreamingService service, final ListLinkHandler li
public abstract String getParentChannelUrl() throws ParsingException;
public abstract String getParentChannelAvatarUrl() throws ParsingException;
public abstract boolean isVerified() throws ParsingException;

@Nonnull
public abstract List<ListLinkHandler> getTabs() throws ParsingException;
@Nonnull
public List<String> getTags() throws ParsingException {
return List.of();
}
}
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -32,16 +31,14 @@
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/

public class ChannelInfo extends ListInfo<StreamInfoItem> {
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 {
Expand All @@ -55,13 +52,6 @@ public static ChannelInfo getInfo(final StreamingService service, final String u
return getInfo(extractor);
}

public static InfoItemsPage<StreamInfoItem> 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 {

Expand All @@ -71,35 +61,32 @@ public static ChannelInfo getInfo(final ChannelExtractor extractor)
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<StreamInfoItem> 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) {
Expand Down Expand Up @@ -130,6 +117,18 @@ public static ChannelInfo getInfo(final ChannelExtractor extractor)
info.addError(e);
}

try {
info.setTabs(extractor.getTabs());
} catch (final Exception e) {
info.addError(e);
}

try {
info.setTags(extractor.getTags());
} catch (final Exception e) {
info.addError(e);
}

return info;
}

Expand All @@ -143,6 +142,8 @@ public static ChannelInfo getInfo(final ChannelExtractor extractor)
private String description;
private String[] donationLinks;
private boolean verified;
private List<ListLinkHandler> tabs = List.of();
private List<String> tags = List.of();

public String getParentChannelName() {
return parentChannelName;
Expand Down Expand Up @@ -223,4 +224,22 @@ public boolean isVerified() {
public void setVerified(final boolean verified) {
this.verified = verified;
}

@Nonnull
public List<ListLinkHandler> getTabs() {
return tabs;
}

public void setTabs(@Nonnull final List<ListLinkHandler> tabs) {
this.tabs = tabs;
}

@Nonnull
public List<String> getTags() {
return tags;
}

public void setTags(@Nonnull final List<String> tags) {
this.tags = tags;
}
}
Original file line number Diff line number Diff line change
@@ -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<InfoItem> {

protected ChannelTabExtractor(@Nonnull final StreamingService service,
@Nonnull final ListLinkHandler linkHandler) {
super(service, linkHandler);
}

@Nonnull
@Override
public String getName() {
return getLinkHandler().getContentFilters().get(0);
}
}
Original file line number Diff line number Diff line change
@@ -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<InfoItem> {

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<InfoItem> page
= ExtractorHelper.getItemsPageOrLogError(info, extractor);
info.setRelatedItems(page.getItems());
info.setNextPage(page.getNextPage());

return info;
}

public static ListExtractor.InfoItemsPage<InfoItem> getMoreItems(
@Nonnull final StreamingService service,
@Nonnull final ListLinkHandler linkHandler,
@Nonnull final Page page) throws ExtractionException, IOException {
return service.getChannelTabExtractor(linkHandler).getPage(page);
}
}
Original file line number Diff line number Diff line change
@@ -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() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.schabi.newpipe.extractor.exceptions;

public final class UnsupportedTabException extends UnsupportedOperationException {
public UnsupportedTabException(final String unsupportedTab) {
super("Unsupported tab " + unsupportedTab);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ public abstract class LinkHandlerFactory {
// To Override
///////////////////////////////////

public abstract String getId(String url) throws ParsingException;
public abstract String getId(String url) throws ParsingException, UnsupportedOperationException;

public abstract String getUrl(String id) throws ParsingException;
public abstract String getUrl(String id) throws ParsingException, UnsupportedOperationException;

public abstract boolean onAcceptUrl(String url) throws ParsingException;

public String getUrl(final String id, final String baseUrl) throws ParsingException {
public String getUrl(final String id, final String baseUrl)
throws ParsingException, UnsupportedOperationException {
return getUrl(id);
}

Expand Down
Loading