[PeerTube] Add tabs support for accounts and video channels
Support of channels and videos has been added for accounts and support of videos and playlists has been added for video channels. The following changes have been also done: - collectStreamsFrom method in PeertubeParsingHelper has been renamed to collectItemsFrom; - PeertubeChannelInfoItemExtractor.getStreamCount method has been fixed due to ChannelExtractor's new inheritance; - the declaration of the UnsupportedOperationException exception thrown has been added to the service's LinkHandlers; - a channel tab LinkHandlerFactory has been added, PeertubeChannelTabLinkHandlerFactory; - all service's LinkHandlers are now using properly the singleton pattern. Co-authored-by: ThetaDev <t.testboy@gmail.com> Co-authored-by: Stypox <stypox@pm.me>
This commit is contained in:
parent
652c2c8408
commit
1e8474b22d
|
@ -6,6 +6,7 @@ import static java.util.Arrays.asList;
|
|||
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
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.kiosk.KioskList;
|
||||
|
@ -13,6 +14,7 @@ import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
|
|||
import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ReadyChannelTabListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.playlist.PlaylistExtractor;
|
||||
|
@ -27,8 +29,6 @@ import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCSearch
|
|||
import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCStreamExtractor;
|
||||
import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCConferenceLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCConferencesListLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCLiveListLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCRecentListLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCSearchQueryHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCStreamLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.stream.StreamExtractor;
|
||||
|
@ -47,12 +47,17 @@ public class MediaCCCService extends StreamingService {
|
|||
|
||||
@Override
|
||||
public LinkHandlerFactory getStreamLHFactory() {
|
||||
return new MediaCCCStreamLinkHandlerFactory();
|
||||
return MediaCCCStreamLinkHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getChannelLHFactory() {
|
||||
return new MediaCCCConferenceLinkHandlerFactory();
|
||||
return MediaCCCConferenceLinkHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getChannelTabLHFactory() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -62,7 +67,7 @@ public class MediaCCCService extends StreamingService {
|
|||
|
||||
@Override
|
||||
public SearchQueryHandlerFactory getSearchQHFactory() {
|
||||
return new MediaCCCSearchQueryHandlerFactory();
|
||||
return MediaCCCSearchQueryHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,6 +83,22 @@ public class MediaCCCService extends StreamingService {
|
|||
return new MediaCCCConferenceExtractor(this, linkHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelTabExtractor getChannelTabExtractor(final ListLinkHandler linkHandler) {
|
||||
if (linkHandler instanceof ReadyChannelTabListLinkHandler) {
|
||||
return ((ReadyChannelTabListLinkHandler) linkHandler).getChannelTabExtractor(this);
|
||||
}
|
||||
|
||||
/*
|
||||
Channel tab extractors are only supported in conferences and should only come from a
|
||||
ReadyChannelTabListLinkHandler instance with a ChannelTabExtractorBuilder instance of the
|
||||
conferences extractor
|
||||
|
||||
If that's not the case, return null in this case, so no channel tabs support
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlaylistExtractor getPlaylistExtractor(final ListLinkHandler linkHandler) {
|
||||
return null;
|
||||
|
@ -91,36 +112,37 @@ public class MediaCCCService extends StreamingService {
|
|||
@Override
|
||||
public KioskList getKioskList() throws ExtractionException {
|
||||
final KioskList list = new KioskList(this);
|
||||
final ListLinkHandlerFactory h = MediaCCCConferencesListLinkHandlerFactory.getInstance();
|
||||
|
||||
// add kiosks here e.g.:
|
||||
try {
|
||||
list.addKioskEntry(
|
||||
(streamingService, url, kioskId) -> new MediaCCCConferenceKiosk(
|
||||
MediaCCCService.this,
|
||||
new MediaCCCConferencesListLinkHandlerFactory().fromUrl(url),
|
||||
h.fromUrl(url),
|
||||
kioskId
|
||||
),
|
||||
new MediaCCCConferencesListLinkHandlerFactory(),
|
||||
h,
|
||||
MediaCCCConferenceKiosk.KIOSK_ID
|
||||
);
|
||||
|
||||
list.addKioskEntry(
|
||||
(streamingService, url, kioskId) -> new MediaCCCRecentKiosk(
|
||||
MediaCCCService.this,
|
||||
new MediaCCCRecentListLinkHandlerFactory().fromUrl(url),
|
||||
h.fromUrl(url),
|
||||
kioskId
|
||||
),
|
||||
new MediaCCCRecentListLinkHandlerFactory(),
|
||||
h,
|
||||
MediaCCCRecentKiosk.KIOSK_ID
|
||||
);
|
||||
|
||||
list.addKioskEntry(
|
||||
(streamingService, url, kioskId) -> new MediaCCCLiveStreamKiosk(
|
||||
MediaCCCService.this,
|
||||
new MediaCCCLiveListLinkHandlerFactory().fromUrl(url),
|
||||
h.fromUrl(url),
|
||||
kioskId
|
||||
),
|
||||
new MediaCCCLiveListLinkHandlerFactory(),
|
||||
h,
|
||||
MediaCCCLiveStreamKiosk.KIOSK_ID
|
||||
);
|
||||
|
||||
|
|
|
@ -1,23 +1,29 @@
|
|||
package org.schabi.newpipe.extractor.services.media_ccc.extractors;
|
||||
|
||||
import com.grack.nanojson.JsonArray;
|
||||
import com.grack.nanojson.JsonObject;
|
||||
import com.grack.nanojson.JsonParser;
|
||||
import com.grack.nanojson.JsonParserException;
|
||||
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.ListExtractor;
|
||||
import org.schabi.newpipe.extractor.MultiInfoItemsCollector;
|
||||
import org.schabi.newpipe.extractor.Page;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabExtractor;
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabs;
|
||||
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.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ReadyChannelTabListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.services.media_ccc.extractors.infoItems.MediaCCCStreamInfoItemExtractor;
|
||||
import org.schabi.newpipe.extractor.services.media_ccc.linkHandler.MediaCCCConferenceLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
|
||||
public class MediaCCCConferenceExtractor extends ChannelExtractor {
|
||||
private JsonObject conferenceData;
|
||||
|
@ -74,18 +80,9 @@ public class MediaCCCConferenceExtractor extends ChannelExtractor {
|
|||
|
||||
@Nonnull
|
||||
@Override
|
||||
public InfoItemsPage<StreamInfoItem> getInitialPage() {
|
||||
final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
|
||||
final JsonArray events = conferenceData.getArray("events");
|
||||
for (int i = 0; i < events.size(); i++) {
|
||||
collector.commit(new MediaCCCStreamInfoItemExtractor(events.getObject(i)));
|
||||
}
|
||||
return new InfoItemsPage<>(collector, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemsPage<StreamInfoItem> getPage(final Page page) {
|
||||
return InfoItemsPage.emptyPage();
|
||||
public List<ListLinkHandler> getTabs() throws ParsingException {
|
||||
return List.of(new ReadyChannelTabListLinkHandler(getUrl(), getId(),
|
||||
ChannelTabs.VIDEOS, new VideosTabExtractorBuilder(conferenceData)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -105,4 +102,55 @@ public class MediaCCCConferenceExtractor extends ChannelExtractor {
|
|||
public String getName() throws ParsingException {
|
||||
return conferenceData.getString("title");
|
||||
}
|
||||
|
||||
private static final class VideosTabExtractorBuilder
|
||||
implements ReadyChannelTabListLinkHandler.ChannelTabExtractorBuilder {
|
||||
|
||||
private final JsonObject conferenceData;
|
||||
|
||||
VideosTabExtractorBuilder(final JsonObject conferenceData) {
|
||||
this.conferenceData = conferenceData;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ChannelTabExtractor build(@Nonnull final StreamingService service,
|
||||
@Nonnull final ListLinkHandler linkHandler) {
|
||||
return new VideosChannelTabExtractor(service, linkHandler, conferenceData);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class VideosChannelTabExtractor extends ChannelTabExtractor {
|
||||
private final JsonObject conferenceData;
|
||||
|
||||
VideosChannelTabExtractor(final StreamingService service,
|
||||
final ListLinkHandler linkHandler,
|
||||
final JsonObject conferenceData) {
|
||||
super(service, linkHandler);
|
||||
this.conferenceData = conferenceData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchPage(@Nonnull final Downloader downloader) {
|
||||
// Nothing to do here, as data was already fetched
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ListExtractor.InfoItemsPage<InfoItem> getInitialPage() {
|
||||
final MultiInfoItemsCollector collector =
|
||||
new MultiInfoItemsCollector(getServiceId());
|
||||
conferenceData.getArray("events")
|
||||
.stream()
|
||||
.filter(JsonObject.class::isInstance)
|
||||
.map(JsonObject.class::cast)
|
||||
.forEach(event -> collector.commit(new MediaCCCStreamInfoItemExtractor(event)));
|
||||
return new InfoItemsPage<>(collector, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemsPage<InfoItem> getPage(final Page page) {
|
||||
return InfoItemsPage.emptyPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ public class MediaCCCRecentKioskExtractor implements StreamInfoItemExtractor {
|
|||
|
||||
@Override
|
||||
public String getUploaderUrl() throws ParsingException {
|
||||
return new MediaCCCConferenceLinkHandlerFactory()
|
||||
return MediaCCCConferenceLinkHandlerFactory.getInstance()
|
||||
.fromUrl(event.getString("conference_url")) // API URL
|
||||
.getUrl(); // web URL
|
||||
}
|
||||
|
|
|
@ -38,7 +38,8 @@ public class MediaCCCSearchExtractor extends SearchExtractor {
|
|||
super(service, linkHandler);
|
||||
try {
|
||||
conferenceKiosk = new MediaCCCConferenceKiosk(service,
|
||||
new MediaCCCConferencesListLinkHandlerFactory().fromId("conferences"),
|
||||
MediaCCCConferencesListLinkHandlerFactory.getInstance()
|
||||
.fromId("conferences"),
|
||||
"conferences");
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -6,7 +6,11 @@ import org.schabi.newpipe.extractor.utils.Parser;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
public class MediaCCCConferenceLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
public final class MediaCCCConferenceLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
|
||||
private static final MediaCCCConferenceLinkHandlerFactory INSTANCE
|
||||
= new MediaCCCConferenceLinkHandlerFactory();
|
||||
|
||||
public static final String CONFERENCE_API_ENDPOINT
|
||||
= "https://api.media.ccc.de/public/conferences/";
|
||||
public static final String CONFERENCE_PATH = "https://media.ccc.de/c/";
|
||||
|
@ -14,15 +18,23 @@ public class MediaCCCConferenceLinkHandlerFactory extends ListLinkHandlerFactory
|
|||
= "(?:(?:(?:api\\.)?media\\.ccc\\.de/public/conferences/)"
|
||||
+ "|(?:media\\.ccc\\.de/[bc]/))([^/?&#]*)";
|
||||
|
||||
private MediaCCCConferenceLinkHandlerFactory() {
|
||||
}
|
||||
|
||||
public static MediaCCCConferenceLinkHandlerFactory getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(final String id,
|
||||
final List<String> contentFilter,
|
||||
final String sortFilter) throws ParsingException {
|
||||
final String sortFilter)
|
||||
throws ParsingException, UnsupportedOperationException {
|
||||
return CONFERENCE_PATH + id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(final String url) throws ParsingException {
|
||||
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
|
||||
return Parser.matchGroup1(ID_PATTERN, url);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,15 +5,28 @@ import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
public class MediaCCCConferencesListLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
public final class MediaCCCConferencesListLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
|
||||
private static final MediaCCCConferencesListLinkHandlerFactory INSTANCE =
|
||||
new MediaCCCConferencesListLinkHandlerFactory();
|
||||
|
||||
private MediaCCCConferencesListLinkHandlerFactory() {
|
||||
}
|
||||
|
||||
public static MediaCCCConferencesListLinkHandlerFactory getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(final String url) throws ParsingException {
|
||||
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
|
||||
return "conferences";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(final String id, final List<String> contentFilter,
|
||||
final String sortFilter) throws ParsingException {
|
||||
public String getUrl(final String id,
|
||||
final List<String> contentFilter,
|
||||
final String sortFilter)
|
||||
throws ParsingException, UnsupportedOperationException {
|
||||
return "https://media.ccc.de/public/conferences";
|
||||
}
|
||||
|
||||
|
|
|
@ -6,11 +6,22 @@ import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
|||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class MediaCCCLiveListLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
public final class MediaCCCLiveListLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
|
||||
private static final MediaCCCLiveListLinkHandlerFactory INSTANCE =
|
||||
new MediaCCCLiveListLinkHandlerFactory();
|
||||
|
||||
private static final String STREAM_PATTERN = "^(?:https?://)?media\\.ccc\\.de/live$";
|
||||
|
||||
private MediaCCCLiveListLinkHandlerFactory() {
|
||||
}
|
||||
|
||||
public static MediaCCCLiveListLinkHandlerFactory getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(final String url) throws ParsingException {
|
||||
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
|
||||
return "live";
|
||||
}
|
||||
|
||||
|
@ -22,7 +33,8 @@ public class MediaCCCLiveListLinkHandlerFactory extends ListLinkHandlerFactory {
|
|||
@Override
|
||||
public String getUrl(final String id,
|
||||
final List<String> contentFilter,
|
||||
final String sortFilter) throws ParsingException {
|
||||
final String sortFilter)
|
||||
throws ParsingException, UnsupportedOperationException {
|
||||
// FIXME: wrong URL; should be https://streaming.media.ccc.de/{conference_slug}/{room_slug}
|
||||
return "https://media.ccc.de/live";
|
||||
}
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
package org.schabi.newpipe.extractor.services.media_ccc.linkHandler;
|
||||
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.utils.Parser;
|
||||
|
||||
public class MediaCCCLiveStreamLinkHandlerFactory extends LinkHandlerFactory {
|
||||
public static final String VIDEO_API_ENDPOINT = "https://api.media.ccc.de/public/events/";
|
||||
private static final String VIDEO_PATH = "https://streaming.media.ccc.de/v/";
|
||||
private static final String ID_PATTERN
|
||||
= "(?:(?:(?:api\\.)?media\\.ccc\\.de/public/events/)"
|
||||
+ "|(?:media\\.ccc\\.de/v/))([^/?&#]*)";
|
||||
|
||||
@Override
|
||||
public String getId(final String url) throws ParsingException {
|
||||
return Parser.matchGroup1(ID_PATTERN, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(final String id) throws ParsingException {
|
||||
return VIDEO_PATH + id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onAcceptUrl(final String url) {
|
||||
try {
|
||||
return getId(url) != null;
|
||||
} catch (final ParsingException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +1,27 @@
|
|||
package org.schabi.newpipe.extractor.services.media_ccc.linkHandler;
|
||||
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class MediaCCCRecentListLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
public final class MediaCCCRecentListLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
|
||||
private static final MediaCCCRecentListLinkHandlerFactory INSTANCE =
|
||||
new MediaCCCRecentListLinkHandlerFactory();
|
||||
|
||||
private static final String PATTERN = "^(https?://)?media\\.ccc\\.de/recent/?$";
|
||||
|
||||
private MediaCCCRecentListLinkHandlerFactory() {
|
||||
}
|
||||
|
||||
public static MediaCCCRecentListLinkHandlerFactory getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(final String url) {
|
||||
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
|
||||
return "recent";
|
||||
}
|
||||
|
||||
|
@ -21,7 +33,8 @@ public class MediaCCCRecentListLinkHandlerFactory extends ListLinkHandlerFactory
|
|||
@Override
|
||||
public String getUrl(final String id,
|
||||
final List<String> contentFilter,
|
||||
final String sortFilter) {
|
||||
final String sortFilter)
|
||||
throws ParsingException, UnsupportedOperationException {
|
||||
return "https://media.ccc.de/recent";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,22 @@ import org.schabi.newpipe.extractor.utils.Utils;
|
|||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.List;
|
||||
|
||||
public class MediaCCCSearchQueryHandlerFactory extends SearchQueryHandlerFactory {
|
||||
public final class MediaCCCSearchQueryHandlerFactory extends SearchQueryHandlerFactory {
|
||||
|
||||
private static final MediaCCCSearchQueryHandlerFactory INSTANCE =
|
||||
new MediaCCCSearchQueryHandlerFactory();
|
||||
|
||||
public static final String ALL = "all";
|
||||
public static final String CONFERENCES = "conferences";
|
||||
public static final String EVENTS = "events";
|
||||
|
||||
private MediaCCCSearchQueryHandlerFactory() {
|
||||
}
|
||||
|
||||
public static MediaCCCSearchQueryHandlerFactory getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAvailableContentFilter() {
|
||||
return new String[]{
|
||||
|
@ -27,8 +38,10 @@ public class MediaCCCSearchQueryHandlerFactory extends SearchQueryHandlerFactory
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(final String query, final List<String> contentFilter,
|
||||
final String sortFilter) throws ParsingException {
|
||||
public String getUrl(final String query,
|
||||
final List<String> contentFilter,
|
||||
final String sortFilter)
|
||||
throws ParsingException, UnsupportedOperationException {
|
||||
try {
|
||||
return "https://media.ccc.de/public/events/search?q=" + Utils.encodeUrlUtf8(query);
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
|
|
|
@ -5,7 +5,11 @@ import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory;
|
|||
import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCParsingHelper;
|
||||
import org.schabi.newpipe.extractor.utils.Parser;
|
||||
|
||||
public class MediaCCCStreamLinkHandlerFactory extends LinkHandlerFactory {
|
||||
public final class MediaCCCStreamLinkHandlerFactory extends LinkHandlerFactory {
|
||||
|
||||
private static final MediaCCCStreamLinkHandlerFactory INSTANCE =
|
||||
new MediaCCCStreamLinkHandlerFactory();
|
||||
|
||||
public static final String VIDEO_API_ENDPOINT = "https://api.media.ccc.de/public/events/";
|
||||
private static final String VIDEO_PATH = "https://media.ccc.de/v/";
|
||||
private static final String RECORDING_ID_PATTERN
|
||||
|
@ -15,8 +19,15 @@ public class MediaCCCStreamLinkHandlerFactory extends LinkHandlerFactory {
|
|||
private static final String LIVE_STREAM_ID_PATTERN
|
||||
= "streaming\\.media\\.ccc\\.de\\/(\\w+\\/\\w+)";
|
||||
|
||||
private MediaCCCStreamLinkHandlerFactory() {
|
||||
}
|
||||
|
||||
public static MediaCCCStreamLinkHandlerFactory getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(final String url) throws ParsingException {
|
||||
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
|
||||
String streamId = null;
|
||||
try {
|
||||
streamId = Parser.matchGroup1(LIVE_STREAM_ID_PATTERN, url);
|
||||
|
@ -30,7 +41,7 @@ public class MediaCCCStreamLinkHandlerFactory extends LinkHandlerFactory {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(final String id) throws ParsingException {
|
||||
public String getUrl(final String id) throws ParsingException, UnsupportedOperationException {
|
||||
if (MediaCCCParsingHelper.isLiveStreamId(id)) {
|
||||
return LIVE_STREAM_PATH + id;
|
||||
}
|
||||
|
|
|
@ -72,24 +72,29 @@ public final class PeertubeParsingHelper {
|
|||
}
|
||||
}
|
||||
|
||||
public static void collectStreamsFrom(final InfoItemsCollector collector,
|
||||
final JsonObject json,
|
||||
final String baseUrl) throws ParsingException {
|
||||
collectStreamsFrom(collector, json, baseUrl, false);
|
||||
public static void collectItemsFrom(final InfoItemsCollector collector,
|
||||
final JsonObject json,
|
||||
final String baseUrl) throws ParsingException {
|
||||
collectItemsFrom(collector, json, baseUrl, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect stream from json with collector
|
||||
* Collect items from the given JSON object with the given collector.
|
||||
*
|
||||
* <p>
|
||||
* Supported info item types are streams with their Sepia variant, channels and playlists.
|
||||
* </p>
|
||||
*
|
||||
* @param collector the collector used to collect information
|
||||
* @param json the file to retrieve data from
|
||||
* @param baseUrl the base Url of the instance
|
||||
* @param sepia if we should use PeertubeSepiaStreamInfoItemExtractor
|
||||
* @param json the JSOn response to retrieve data from
|
||||
* @param baseUrl the base URL of the instance
|
||||
* @param sepia if we should use {@code PeertubeSepiaStreamInfoItemExtractor} to extract
|
||||
* streams or {@code PeertubeStreamInfoItemExtractor} otherwise
|
||||
*/
|
||||
public static void collectStreamsFrom(final InfoItemsCollector collector,
|
||||
final JsonObject json,
|
||||
final String baseUrl,
|
||||
final boolean sepia) throws ParsingException {
|
||||
public static void collectItemsFrom(final InfoItemsCollector collector,
|
||||
final JsonObject json,
|
||||
final String baseUrl,
|
||||
final boolean sepia) throws ParsingException {
|
||||
final JsonArray contents;
|
||||
try {
|
||||
contents = (JsonArray) JsonUtils.getValue(json, "data");
|
||||
|
|
|
@ -6,6 +6,7 @@ import static java.util.Arrays.asList;
|
|||
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
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.kiosk.KioskList;
|
||||
|
@ -19,6 +20,7 @@ import org.schabi.newpipe.extractor.playlist.PlaylistExtractor;
|
|||
import org.schabi.newpipe.extractor.search.SearchExtractor;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeAccountExtractor;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeChannelExtractor;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeChannelTabExtractor;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeCommentsExtractor;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubePlaylistExtractor;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeSearchExtractor;
|
||||
|
@ -26,6 +28,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;
|
||||
|
@ -60,6 +63,11 @@ public class PeertubeService extends StreamingService {
|
|||
return PeertubeChannelLinkHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getChannelTabLHFactory() {
|
||||
return PeertubeChannelTabLinkHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getPlaylistLHFactory() {
|
||||
return PeertubePlaylistLinkHandlerFactory.getInstance();
|
||||
|
@ -103,6 +111,12 @@ public class PeertubeService extends StreamingService {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelTabExtractor getChannelTabExtractor(final ListLinkHandler linkHandler)
|
||||
throws ExtractionException {
|
||||
return new PeertubeChannelTabExtractor(this, linkHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlaylistExtractor getPlaylistExtractor(final ListLinkHandler linkHandler)
|
||||
throws ExtractionException {
|
||||
|
@ -136,17 +150,20 @@ public class PeertubeService extends StreamingService {
|
|||
|
||||
@Override
|
||||
public KioskList getKioskList() throws ExtractionException {
|
||||
final PeertubeTrendingLinkHandlerFactory h =
|
||||
PeertubeTrendingLinkHandlerFactory.getInstance();
|
||||
|
||||
final KioskList.KioskExtractorFactory kioskFactory = (streamingService, url, id) ->
|
||||
new PeertubeTrendingExtractor(
|
||||
PeertubeService.this,
|
||||
new PeertubeTrendingLinkHandlerFactory().fromId(id),
|
||||
h.fromId(id),
|
||||
id
|
||||
);
|
||||
|
||||
final KioskList list = new KioskList(this);
|
||||
|
||||
// add kiosks here e.g.:
|
||||
final PeertubeTrendingLinkHandlerFactory h = new PeertubeTrendingLinkHandlerFactory();
|
||||
|
||||
try {
|
||||
list.addKioskEntry(kioskFactory, h, PeertubeTrendingLinkHandlerFactory.KIOSK_TRENDING);
|
||||
list.addKioskEntry(kioskFactory, h,
|
||||
|
@ -160,6 +177,4 @@ public class PeertubeService extends StreamingService {
|
|||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -4,31 +4,23 @@ import com.grack.nanojson.JsonArray;
|
|||
import com.grack.nanojson.JsonObject;
|
||||
import com.grack.nanojson.JsonParser;
|
||||
import com.grack.nanojson.JsonParserException;
|
||||
import org.schabi.newpipe.extractor.Page;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabs;
|
||||
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.exceptions.ReCaptchaException;
|
||||
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.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelTabLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.utils.JsonUtils;
|
||||
import org.schabi.newpipe.extractor.utils.Utils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.COUNT_KEY;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.ITEMS_PER_PAGE;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.START_KEY;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.collectStreamsFrom;
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||
import java.util.List;
|
||||
|
||||
public class PeertubeAccountExtractor extends ChannelExtractor {
|
||||
private JsonObject json;
|
||||
|
@ -119,54 +111,19 @@ public class PeertubeAccountExtractor extends ChannelExtractor {
|
|||
|
||||
@Nonnull
|
||||
@Override
|
||||
public InfoItemsPage<StreamInfoItem> getInitialPage() throws IOException, ExtractionException {
|
||||
return getPage(new Page(baseUrl + "/api/v1/" + getId() + "/videos?" + START_KEY + "=0&"
|
||||
+ COUNT_KEY + "=" + ITEMS_PER_PAGE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemsPage<StreamInfoItem> getPage(final Page page)
|
||||
throws IOException, ExtractionException {
|
||||
if (page == null || isNullOrEmpty(page.getUrl())) {
|
||||
throw new IllegalArgumentException("Page doesn't contain an URL");
|
||||
}
|
||||
|
||||
final Response response = getDownloader().get(page.getUrl());
|
||||
|
||||
JsonObject pageJson = null;
|
||||
if (response != null && !Utils.isBlank(response.responseBody())) {
|
||||
try {
|
||||
pageJson = JsonParser.object().from(response.responseBody());
|
||||
} catch (final Exception e) {
|
||||
throw new ParsingException("Could not parse json data for account info", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (pageJson != null) {
|
||||
PeertubeParsingHelper.validate(pageJson);
|
||||
final long total = pageJson.getLong("total");
|
||||
|
||||
final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
|
||||
collectStreamsFrom(collector, pageJson, getBaseUrl());
|
||||
|
||||
return new InfoItemsPage<>(collector,
|
||||
PeertubeParsingHelper.getNextPage(page.getUrl(), total));
|
||||
} else {
|
||||
throw new ExtractionException("Unable to get PeerTube account info");
|
||||
}
|
||||
public List<ListLinkHandler> getTabs() throws ParsingException {
|
||||
return List.of(
|
||||
PeertubeChannelTabLinkHandlerFactory.getInstance().fromQuery(getId(),
|
||||
List.of(ChannelTabs.VIDEOS), "", getBaseUrl()),
|
||||
PeertubeChannelTabLinkHandlerFactory.getInstance().fromQuery(getId(),
|
||||
List.of(ChannelTabs.CHANNELS), "", getBaseUrl()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchPage(@Nonnull final Downloader downloader)
|
||||
throws IOException, ExtractionException {
|
||||
String accountUrl = baseUrl + PeertubeChannelLinkHandlerFactory.API_ENDPOINT;
|
||||
if (getId().contains(ACCOUNTS)) {
|
||||
accountUrl += getId();
|
||||
} else {
|
||||
accountUrl += ACCOUNTS + getId();
|
||||
}
|
||||
|
||||
final Response response = downloader.get(accountUrl);
|
||||
final Response response = downloader.get(baseUrl
|
||||
+ PeertubeChannelLinkHandlerFactory.API_ENDPOINT + getId());
|
||||
if (response != null) {
|
||||
setInitialData(response.responseBody());
|
||||
} else {
|
||||
|
|
|
@ -3,30 +3,22 @@ package org.schabi.newpipe.extractor.services.peertube.extractors;
|
|||
import com.grack.nanojson.JsonObject;
|
||||
import com.grack.nanojson.JsonParser;
|
||||
import com.grack.nanojson.JsonParserException;
|
||||
import org.schabi.newpipe.extractor.Page;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabs;
|
||||
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.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelTabLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.utils.JsonUtils;
|
||||
import org.schabi.newpipe.extractor.utils.Utils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.COUNT_KEY;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.ITEMS_PER_PAGE;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.START_KEY;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.collectStreamsFrom;
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||
import java.util.List;
|
||||
|
||||
public class PeertubeChannelExtractor extends ChannelExtractor {
|
||||
private JsonObject json;
|
||||
|
@ -98,41 +90,12 @@ public class PeertubeChannelExtractor extends ChannelExtractor {
|
|||
|
||||
@Nonnull
|
||||
@Override
|
||||
public InfoItemsPage<StreamInfoItem> getInitialPage() throws IOException, ExtractionException {
|
||||
return getPage(new Page(baseUrl + "/api/v1/" + getId() + "/videos?" + START_KEY + "=0&"
|
||||
+ COUNT_KEY + "=" + ITEMS_PER_PAGE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemsPage<StreamInfoItem> getPage(final Page page)
|
||||
throws IOException, ExtractionException {
|
||||
if (page == null || isNullOrEmpty(page.getUrl())) {
|
||||
throw new IllegalArgumentException("Page doesn't contain an URL");
|
||||
}
|
||||
|
||||
final Response response = getDownloader().get(page.getUrl());
|
||||
|
||||
JsonObject pageJson = null;
|
||||
if (response != null && !Utils.isBlank(response.responseBody())) {
|
||||
try {
|
||||
pageJson = JsonParser.object().from(response.responseBody());
|
||||
} catch (final Exception e) {
|
||||
throw new ParsingException("Could not parse json data for channel info", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (pageJson != null) {
|
||||
PeertubeParsingHelper.validate(pageJson);
|
||||
final long total = pageJson.getLong("total");
|
||||
|
||||
final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
|
||||
collectStreamsFrom(collector, pageJson, getBaseUrl());
|
||||
|
||||
return new InfoItemsPage<>(collector,
|
||||
PeertubeParsingHelper.getNextPage(page.getUrl(), total));
|
||||
} else {
|
||||
throw new ExtractionException("Unable to get PeerTube channel info");
|
||||
}
|
||||
public List<ListLinkHandler> getTabs() throws ParsingException {
|
||||
return List.of(
|
||||
PeertubeChannelTabLinkHandlerFactory.getInstance().fromQuery(getId(),
|
||||
List.of(ChannelTabs.VIDEOS), "", getBaseUrl()),
|
||||
PeertubeChannelTabLinkHandlerFactory.getInstance().fromQuery(getId(),
|
||||
List.of(ChannelTabs.PLAYLISTS), "", getBaseUrl()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.extractors;
|
||||
|
||||
import com.grack.nanojson.JsonObject;
|
||||
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
||||
import org.schabi.newpipe.extractor.ListExtractor;
|
||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
|
||||
|
@ -52,7 +52,7 @@ public class PeertubeChannelInfoItemExtractor implements ChannelInfoItemExtracto
|
|||
|
||||
@Override
|
||||
public long getStreamCount() throws ParsingException {
|
||||
return ChannelExtractor.ITEM_COUNT_UNKNOWN;
|
||||
return ListExtractor.ITEM_COUNT_UNKNOWN;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.extractors;
|
||||
|
||||
import com.grack.nanojson.JsonObject;
|
||||
import com.grack.nanojson.JsonParser;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.MultiInfoItemsCollector;
|
||||
import org.schabi.newpipe.extractor.Page;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabExtractor;
|
||||
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.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;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.COUNT_KEY;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.ITEMS_PER_PAGE;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.START_KEY;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.collectItemsFrom;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelTabLinkHandlerFactory.getUrlSuffix;
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||
|
||||
public class PeertubeChannelTabExtractor extends ChannelTabExtractor {
|
||||
private final String baseUrl;
|
||||
|
||||
public PeertubeChannelTabExtractor(final StreamingService service,
|
||||
final ListLinkHandler linkHandler)
|
||||
throws ParsingException {
|
||||
super(service, linkHandler);
|
||||
baseUrl = getBaseUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchPage(@Nonnull final Downloader downloader) {
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public InfoItemsPage<InfoItem> getInitialPage() throws IOException, ExtractionException {
|
||||
return getPage(new Page(baseUrl + PeertubeChannelLinkHandlerFactory.API_ENDPOINT
|
||||
+ getId() + getUrlSuffix(getName()) + "?" + START_KEY + "=0&" + COUNT_KEY + "="
|
||||
+ ITEMS_PER_PAGE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemsPage<InfoItem> getPage(final Page page)
|
||||
throws IOException, ExtractionException {
|
||||
if (page == null || isNullOrEmpty(page.getUrl())) {
|
||||
throw new IllegalArgumentException("Page doesn't contain an URL");
|
||||
}
|
||||
|
||||
final Response response = getDownloader().get(page.getUrl());
|
||||
|
||||
JsonObject pageJson = null;
|
||||
if (response != null && !Utils.isBlank(response.responseBody())) {
|
||||
try {
|
||||
pageJson = JsonParser.object().from(response.responseBody());
|
||||
} catch (final Exception e) {
|
||||
throw new ParsingException("Could not parse json data for account info", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (pageJson == null) {
|
||||
throw new ExtractionException("Unable to get account channel list");
|
||||
}
|
||||
PeertubeParsingHelper.validate(pageJson);
|
||||
|
||||
final MultiInfoItemsCollector collector = new MultiInfoItemsCollector(getServiceId());
|
||||
collectItemsFrom(collector, pageJson, getBaseUrl());
|
||||
|
||||
return new InfoItemsPage<>(collector,
|
||||
PeertubeParsingHelper.getNextPage(page.getUrl(), pageJson.getLong("total")));
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ import java.io.IOException;
|
|||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.COUNT_KEY;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.ITEMS_PER_PAGE;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.START_KEY;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.collectStreamsFrom;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.collectItemsFrom;
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||
|
||||
public class PeertubePlaylistExtractor extends PlaylistExtractor {
|
||||
|
@ -125,7 +125,7 @@ public class PeertubePlaylistExtractor extends PlaylistExtractor {
|
|||
final long total = json.getLong("total");
|
||||
|
||||
final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
|
||||
collectStreamsFrom(collector, json, getBaseUrl());
|
||||
collectItemsFrom(collector, json, getBaseUrl());
|
||||
|
||||
return new InfoItemsPage<>(collector,
|
||||
PeertubeParsingHelper.getNextPage(page.getUrl(), total));
|
||||
|
|
|
@ -26,7 +26,7 @@ import javax.annotation.Nonnull;
|
|||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.COUNT_KEY;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.ITEMS_PER_PAGE;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.START_KEY;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.collectStreamsFrom;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.collectItemsFrom;
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||
|
||||
public class PeertubeSearchExtractor extends SearchExtractor {
|
||||
|
@ -93,7 +93,7 @@ public class PeertubeSearchExtractor extends SearchExtractor {
|
|||
final long total = json.getLong("total");
|
||||
|
||||
final MultiInfoItemsCollector collector = new MultiInfoItemsCollector(getServiceId());
|
||||
collectStreamsFrom(collector, json, getBaseUrl(), sepia);
|
||||
collectItemsFrom(collector, json, getBaseUrl(), sepia);
|
||||
|
||||
return new InfoItemsPage<>(collector,
|
||||
PeertubeParsingHelper.getNextPage(page.getUrl(), total));
|
||||
|
|
|
@ -23,7 +23,7 @@ import javax.annotation.Nonnull;
|
|||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.COUNT_KEY;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.ITEMS_PER_PAGE;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.START_KEY;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.collectStreamsFrom;
|
||||
import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.collectItemsFrom;
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||
|
||||
public class PeertubeTrendingExtractor extends KioskExtractor<StreamInfoItem> {
|
||||
|
@ -69,7 +69,7 @@ public class PeertubeTrendingExtractor extends KioskExtractor<StreamInfoItem> {
|
|||
final long total = json.getLong("total");
|
||||
|
||||
final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
|
||||
collectStreamsFrom(collector, json, getBaseUrl());
|
||||
collectItemsFrom(collector, json, getBaseUrl());
|
||||
|
||||
return new InfoItemsPage<>(collector,
|
||||
PeertubeParsingHelper.getNextPage(page.getUrl(), total));
|
||||
|
|
|
@ -22,14 +22,15 @@ public final class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFact
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getId(final String url) throws ParsingException {
|
||||
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
|
||||
return fixId(Parser.matchGroup(ID_PATTERN, url, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(final String id,
|
||||
final List<String> contentFilters,
|
||||
final String searchFilter) throws ParsingException {
|
||||
final String searchFilter)
|
||||
throws ParsingException, UnsupportedOperationException {
|
||||
return getUrl(id, contentFilters, searchFilter, ServiceList.PeerTube.getBaseUrl());
|
||||
}
|
||||
|
||||
|
@ -38,7 +39,7 @@ public final class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFact
|
|||
final List<String> contentFilter,
|
||||
final String sortFilter,
|
||||
final String baseUrl)
|
||||
throws ParsingException {
|
||||
throws ParsingException, UnsupportedOperationException {
|
||||
if (id.matches(ID_PATTERN)) {
|
||||
return baseUrl + "/" + fixId(id);
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.linkHandler;
|
||||
|
||||
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabs;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.exceptions.UnsupportedTabException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
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;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static String getUrlSuffix(@Nonnull final String tab)
|
||||
throws UnsupportedTabException {
|
||||
switch (tab) {
|
||||
case ChannelTabs.VIDEOS:
|
||||
return "/videos";
|
||||
case ChannelTabs.CHANNELS: // only available on accounts
|
||||
return "/video-channels";
|
||||
case ChannelTabs.PLAYLISTS: // only available on channels
|
||||
return "/video-playlists";
|
||||
}
|
||||
throw new UnsupportedTabException(tab);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
|
||||
return PeertubeChannelLinkHandlerFactory.getInstance().getId(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(final String id, final List<String> contentFilter, final String sortFilter)
|
||||
throws ParsingException, UnsupportedOperationException {
|
||||
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, UnsupportedOperationException {
|
||||
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.VIDEOS,
|
||||
ChannelTabs.CHANNELS,
|
||||
ChannelTabs.PLAYLISTS,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -21,7 +21,7 @@ public final class PeertubeCommentsLinkHandlerFactory extends ListLinkHandlerFac
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getId(final String url) throws ParsingException, IllegalArgumentException {
|
||||
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
|
||||
return PeertubeStreamLinkHandlerFactory.getInstance().getId(url); // the same id is needed
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,8 @@ public final class PeertubeCommentsLinkHandlerFactory extends ListLinkHandlerFac
|
|||
@Override
|
||||
public String getUrl(final String id,
|
||||
final List<String> contentFilter,
|
||||
final String sortFilter) throws ParsingException {
|
||||
final String sortFilter)
|
||||
throws ParsingException, UnsupportedOperationException {
|
||||
return getUrl(id, contentFilter, sortFilter, ServiceList.PeerTube.getBaseUrl());
|
||||
}
|
||||
|
||||
|
@ -41,7 +42,8 @@ public final class PeertubeCommentsLinkHandlerFactory extends ListLinkHandlerFac
|
|||
public String getUrl(final String id,
|
||||
final List<String> contentFilter,
|
||||
final String sortFilter,
|
||||
final String baseUrl) throws ParsingException {
|
||||
final String baseUrl)
|
||||
throws ParsingException, UnsupportedOperationException {
|
||||
return baseUrl + String.format(COMMENTS_ENDPOINT, id);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,8 @@ public final class PeertubePlaylistLinkHandlerFactory extends ListLinkHandlerFac
|
|||
@Override
|
||||
public String getUrl(final String id,
|
||||
final List<String> contentFilters,
|
||||
final String sortFilter) {
|
||||
final String sortFilter)
|
||||
throws ParsingException, UnsupportedOperationException {
|
||||
return getUrl(id, contentFilters, sortFilter, ServiceList.PeerTube.getBaseUrl());
|
||||
}
|
||||
|
||||
|
@ -33,12 +34,13 @@ public final class PeertubePlaylistLinkHandlerFactory extends ListLinkHandlerFac
|
|||
public String getUrl(final String id,
|
||||
final List<String> contentFilters,
|
||||
final String sortFilter,
|
||||
final String baseUrl) {
|
||||
final String baseUrl)
|
||||
throws ParsingException, UnsupportedOperationException {
|
||||
return baseUrl + "/api/v1/video-playlists/" + id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(final String url) throws ParsingException {
|
||||
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
|
||||
try {
|
||||
return Parser.matchGroup(ID_PATTERN, url, 2);
|
||||
} catch (final ParsingException ignored) {
|
||||
|
|
|
@ -10,6 +10,9 @@ import java.util.List;
|
|||
|
||||
public final class PeertubeSearchQueryHandlerFactory extends SearchQueryHandlerFactory {
|
||||
|
||||
private static final PeertubeSearchQueryHandlerFactory INSTANCE =
|
||||
new PeertubeSearchQueryHandlerFactory();
|
||||
|
||||
public static final String VIDEOS = "videos";
|
||||
public static final String SEPIA_VIDEOS = "sepia_videos"; // sepia is the global index
|
||||
public static final String PLAYLISTS = "playlists";
|
||||
|
@ -23,13 +26,14 @@ public final class PeertubeSearchQueryHandlerFactory extends SearchQueryHandlerF
|
|||
}
|
||||
|
||||
public static PeertubeSearchQueryHandlerFactory getInstance() {
|
||||
return new PeertubeSearchQueryHandlerFactory();
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(final String searchString,
|
||||
final List<String> contentFilters,
|
||||
final String sortFilter) throws ParsingException {
|
||||
final String sortFilter)
|
||||
throws ParsingException, UnsupportedOperationException {
|
||||
final String baseUrl;
|
||||
if (!contentFilters.isEmpty() && contentFilters.get(0).startsWith("sepia_")) {
|
||||
baseUrl = SEPIA_BASE_URL;
|
||||
|
@ -43,7 +47,8 @@ public final class PeertubeSearchQueryHandlerFactory extends SearchQueryHandlerF
|
|||
public String getUrl(final String searchString,
|
||||
final List<String> contentFilters,
|
||||
final String sortFilter,
|
||||
final String baseUrl) throws ParsingException {
|
||||
final String baseUrl)
|
||||
throws ParsingException, UnsupportedOperationException {
|
||||
try {
|
||||
final String endpoint;
|
||||
if (contentFilters.isEmpty()
|
||||
|
|
|
@ -27,7 +27,7 @@ public final class PeertubeStreamLinkHandlerFactory extends LinkHandlerFactory {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(final String id) {
|
||||
public String getUrl(final String id) throws ParsingException, UnsupportedOperationException {
|
||||
return getUrl(id, ServiceList.PeerTube.getBaseUrl());
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ public final class PeertubeStreamLinkHandlerFactory extends LinkHandlerFactory {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getId(final String url) throws ParsingException, IllegalArgumentException {
|
||||
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
|
||||
return Parser.matchGroup(ID_PATTERN, url, 4);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,9 @@ public final class PeertubeTrendingLinkHandlerFactory extends ListLinkHandlerFac
|
|||
KIOSK_RECENT, "%s/api/v1/videos?sort=-publishedAt",
|
||||
KIOSK_LOCAL, "%s/api/v1/videos?sort=-publishedAt&filter=local");
|
||||
|
||||
private PeertubeTrendingLinkHandlerFactory() {
|
||||
}
|
||||
|
||||
public static PeertubeTrendingLinkHandlerFactory getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
@ -30,7 +33,8 @@ public final class PeertubeTrendingLinkHandlerFactory extends ListLinkHandlerFac
|
|||
@Override
|
||||
public String getUrl(final String id,
|
||||
final List<String> contentFilters,
|
||||
final String sortFilter) {
|
||||
final String sortFilter)
|
||||
throws ParsingException, UnsupportedOperationException {
|
||||
return getUrl(id, contentFilters, sortFilter, ServiceList.PeerTube.getBaseUrl());
|
||||
}
|
||||
|
||||
|
@ -38,12 +42,13 @@ public final class PeertubeTrendingLinkHandlerFactory extends ListLinkHandlerFac
|
|||
public String getUrl(final String id,
|
||||
final List<String> contentFilters,
|
||||
final String sortFilter,
|
||||
final String baseUrl) {
|
||||
final String baseUrl)
|
||||
throws ParsingException, UnsupportedOperationException {
|
||||
return String.format(KIOSK_MAP.get(id), baseUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(final String url) throws ParsingException {
|
||||
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
|
||||
final String cleanUrl = url.replace(ServiceList.PeerTube.getBaseUrl(), "%s");
|
||||
if (cleanUrl.contains("/videos/trending")) {
|
||||
return KIOSK_TRENDING;
|
||||
|
|
Loading…
Reference in New Issue