add channel and strem extractor for mediaccc
This commit is contained in:
parent
ef576341c8
commit
2148edc7d7
|
@ -38,5 +38,4 @@ public abstract class ChannelExtractor extends ListExtractor<StreamInfoItem> {
|
||||||
public abstract String getFeedUrl() throws ParsingException;
|
public abstract String getFeedUrl() throws ParsingException;
|
||||||
public abstract long getSubscriberCount() throws ParsingException;
|
public abstract long getSubscriberCount() throws ParsingException;
|
||||||
public abstract String getDescription() throws ParsingException;
|
public abstract String getDescription() throws ParsingException;
|
||||||
public abstract String[] getDonationLinks() throws ParsingException;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,11 +92,6 @@ public class ChannelInfo extends ListInfo<StreamInfoItem> {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
info.addError(e);
|
info.addError(e);
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
info.setDonationLinks(extractor.getDonationLinks());
|
|
||||||
} catch (Exception e) {
|
|
||||||
info.addError(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,12 @@ import org.schabi.newpipe.extractor.kiosk.KioskList;
|
||||||
import org.schabi.newpipe.extractor.linkhandler.*;
|
import org.schabi.newpipe.extractor.linkhandler.*;
|
||||||
import org.schabi.newpipe.extractor.playlist.PlaylistExtractor;
|
import org.schabi.newpipe.extractor.playlist.PlaylistExtractor;
|
||||||
import org.schabi.newpipe.extractor.search.SearchExtractor;
|
import org.schabi.newpipe.extractor.search.SearchExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCConferenceExtractor;
|
||||||
import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCSearchExtractor;
|
import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCSearchExtractor;
|
||||||
|
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.MediaCCCSearchQueryHandlerFactory;
|
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;
|
import org.schabi.newpipe.extractor.stream.StreamExtractor;
|
||||||
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
|
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
|
||||||
import org.schabi.newpipe.extractor.utils.Localization;
|
import org.schabi.newpipe.extractor.utils.Localization;
|
||||||
|
@ -29,12 +33,12 @@ public class MediaCCCService extends StreamingService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LinkHandlerFactory getStreamLHFactory() {
|
public LinkHandlerFactory getStreamLHFactory() {
|
||||||
return null;
|
return new MediaCCCStreamLinkHandlerFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListLinkHandlerFactory getChannelLHFactory() {
|
public ListLinkHandlerFactory getChannelLHFactory() {
|
||||||
return null;
|
return new MediaCCCConferenceLinkHandlerFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -49,12 +53,12 @@ public class MediaCCCService extends StreamingService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StreamExtractor getStreamExtractor(LinkHandler linkHandler, Localization localization) {
|
public StreamExtractor getStreamExtractor(LinkHandler linkHandler, Localization localization) {
|
||||||
return null;
|
return new MediaCCCStreamExtractor(this, linkHandler, localization);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelExtractor getChannelExtractor(ListLinkHandler linkHandler, Localization localization) {
|
public ChannelExtractor getChannelExtractor(ListLinkHandler linkHandler, Localization localization) {
|
||||||
return null;
|
return new MediaCCCConferenceExtractor(this, linkHandler, localization);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
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.Downloader;
|
||||||
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
|
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
||||||
|
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.media_ccc.extractors.infoItems.MediaCCCStreamInfoItemExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||||
|
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
||||||
|
import org.schabi.newpipe.extractor.utils.Localization;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class MediaCCCConferenceExtractor extends ChannelExtractor {
|
||||||
|
|
||||||
|
private JsonObject conferenceData;
|
||||||
|
|
||||||
|
public MediaCCCConferenceExtractor(StreamingService service, ListLinkHandler linkHandler, Localization localization) {
|
||||||
|
super(service, linkHandler, localization);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAvatarUrl() throws ParsingException {
|
||||||
|
return conferenceData.getString("logo_url");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getBannerUrl() throws ParsingException {
|
||||||
|
return conferenceData.getString("logo_url");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFeedUrl() throws ParsingException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getSubscriberCount() throws ParsingException {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() throws ParsingException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public InfoItemsPage<StreamInfoItem> getInitialPage() throws IOException, ExtractionException {
|
||||||
|
StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
|
||||||
|
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 String getNextPageUrl() throws IOException, ExtractionException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InfoItemsPage<StreamInfoItem> getPage(String pageUrl) throws IOException, ExtractionException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFetchPage(@Nonnull Downloader downloader) throws IOException, ExtractionException {
|
||||||
|
try {
|
||||||
|
conferenceData = JsonParser.object().from(downloader.download(getUrl()));
|
||||||
|
} catch (JsonParserException jpe) {
|
||||||
|
throw new ExtractionException("Could not parse json returnd by url: " + getUrl());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String getName() throws ParsingException {
|
||||||
|
return conferenceData.getString("title");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getOriginalUrl() throws ParsingException {
|
||||||
|
return "https://media.ccc.de/c/" + conferenceData.getString("acronym");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,222 @@
|
||||||
|
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.Downloader;
|
||||||
|
import org.schabi.newpipe.extractor.MediaFormat;
|
||||||
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
|
import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
|
||||||
|
import org.schabi.newpipe.extractor.stream.*;
|
||||||
|
import org.schabi.newpipe.extractor.utils.Localization;
|
||||||
|
import org.schabi.newpipe.extractor.utils.Parser;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MediaCCCStreamExtractor extends StreamExtractor {
|
||||||
|
|
||||||
|
private JsonObject data;
|
||||||
|
private JsonObject conferenceData;
|
||||||
|
|
||||||
|
public MediaCCCStreamExtractor(StreamingService service, LinkHandler linkHandler, Localization localization) {
|
||||||
|
super(service, linkHandler, localization);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String getUploadDate() throws ParsingException {
|
||||||
|
return data.getString("release_date");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String getThumbnailUrl() throws ParsingException {
|
||||||
|
return data.getString("thumb_url");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String getDescription() throws ParsingException {
|
||||||
|
return data.getString("description");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAgeLimit() throws ParsingException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLength() throws ParsingException {
|
||||||
|
return data.getInt("length");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getTimeStamp() throws ParsingException {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getViewCount() throws ParsingException {
|
||||||
|
return data.getInt("view_count");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLikeCount() throws ParsingException {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getDislikeCount() throws ParsingException {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String getUploaderUrl() throws ParsingException {
|
||||||
|
return data.getString("conference_url");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String getUploaderName() throws ParsingException {
|
||||||
|
return data.getString("conference_url")
|
||||||
|
.replace("https://api.media.ccc.de/public/conferences/", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String getUploaderAvatarUrl() throws ParsingException {
|
||||||
|
return conferenceData.getString("logo_url");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String getDashMpdUrl() throws ParsingException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String getHlsUrl() throws ParsingException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AudioStream> getAudioStreams() throws IOException, ExtractionException {
|
||||||
|
final JsonArray recordings = data.getArray("recordings");
|
||||||
|
final List<AudioStream> audioStreams = new ArrayList<>();
|
||||||
|
for(int i = 0; i < recordings.size(); i++) {
|
||||||
|
final JsonObject recording = recordings.getObject(i);
|
||||||
|
final String mimeType = recording.getString("mime_type");
|
||||||
|
if(mimeType.startsWith("audio")) {
|
||||||
|
//first we need to resolve the actual video data from CDN
|
||||||
|
final MediaFormat mediaFormat;
|
||||||
|
if(mimeType.endsWith("opus")) {
|
||||||
|
mediaFormat = MediaFormat.OPUS;
|
||||||
|
} else if(mimeType.endsWith("mpeg")) {
|
||||||
|
mediaFormat = MediaFormat.MP3;
|
||||||
|
} else {
|
||||||
|
throw new ExtractionException("Unknown media format: " + mimeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
audioStreams.add(new AudioStream(recording.getString("recording_url"), mediaFormat, -1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return audioStreams;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<VideoStream> getVideoStreams() throws IOException, ExtractionException {
|
||||||
|
final JsonArray recordings = data.getArray("recordings");
|
||||||
|
final List<VideoStream> videoStreams = new ArrayList<>();
|
||||||
|
for(int i = 0; i < recordings.size(); i++) {
|
||||||
|
final JsonObject recording = recordings.getObject(i);
|
||||||
|
final String mimeType = recording.getString("mime_type");
|
||||||
|
if(mimeType.startsWith("video")) {
|
||||||
|
//first we need to resolve the actual video data from CDN
|
||||||
|
|
||||||
|
final MediaFormat mediaFormat;
|
||||||
|
if(mimeType.endsWith("webm")) {
|
||||||
|
mediaFormat = MediaFormat.WEBM;
|
||||||
|
} else if(mimeType.endsWith("mp4")) {
|
||||||
|
mediaFormat = MediaFormat.MPEG_4;
|
||||||
|
} else {
|
||||||
|
throw new ExtractionException("Unknown media format: " + mimeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
videoStreams.add(new VideoStream(recording.getString("recording_url"),
|
||||||
|
mediaFormat,
|
||||||
|
Integer.toString(recording.getInt("height"))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return videoStreams;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<VideoStream> getVideoOnlyStreams() throws IOException, ExtractionException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public List<SubtitlesStream> getSubtitlesDefault() throws IOException, ExtractionException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public List<SubtitlesStream> getSubtitles(MediaFormat format) throws IOException, ExtractionException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StreamType getStreamType() throws ParsingException {
|
||||||
|
return StreamType.VIDEO_STREAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StreamInfoItem getNextStream() throws IOException, ExtractionException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StreamInfoItemsCollector getRelatedStreams() throws IOException, ExtractionException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getErrorMessage() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFetchPage(@Nonnull Downloader downloader) throws IOException, ExtractionException {
|
||||||
|
try {
|
||||||
|
data = JsonParser.object().from(
|
||||||
|
downloader.download(getLinkHandler().getUrl()));
|
||||||
|
conferenceData = JsonParser.object()
|
||||||
|
.from(downloader.download(getUploaderUrl()));
|
||||||
|
} catch (JsonParserException jpe) {
|
||||||
|
throw new ExtractionException("Could not parse json returned by url: " + getLinkHandler().getUrl(), jpe);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String getName() throws ParsingException {
|
||||||
|
return data.getString("title");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getOriginalUrl() throws ParsingException {
|
||||||
|
return data.getString("frontend_link");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package org.schabi.newpipe.extractor.services.media_ccc.extractors;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.extractor.SuggestionExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
|
import org.schabi.newpipe.extractor.utils.Localization;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MediaCCCSuggestionExtractor extends SuggestionExtractor {
|
||||||
|
|
||||||
|
public MediaCCCSuggestionExtractor(int serviceId, Localization localization) {
|
||||||
|
super(serviceId, localization);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> suggestionList(String query) throws IOException, ExtractionException {
|
||||||
|
return new ArrayList<>(0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -62,6 +62,6 @@ public class MediaCCCStreamInfoItemExtractor implements StreamInfoItemExtractor
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getThumbnailUrl() throws ParsingException {
|
public String getThumbnailUrl() throws ParsingException {
|
||||||
return event.getString("thumbnails_url");
|
return event.getString("thumb_url");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package org.schabi.newpipe.extractor.services.media_ccc.linkHandler;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
|
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
||||||
|
import org.schabi.newpipe.extractor.utils.Parser;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MediaCCCConferenceLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUrl(String id, List<String> contentFilter, String sortFilter) throws ParsingException {
|
||||||
|
return "https://api.media.ccc.de/public/conferences/" + id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId(String url) throws ParsingException {
|
||||||
|
if(url.startsWith("https://api.media.ccc.de/public/conferences/")) {
|
||||||
|
return url.replace("https://api.media.ccc.de/public/conferences/", "");
|
||||||
|
} else if(url.startsWith("https://media.ccc.de/c/")) {
|
||||||
|
return Parser.matchGroup1("https://media.ccc.de/c/([^?#]*)", url);
|
||||||
|
} else {
|
||||||
|
throw new ParsingException("Could not get id from url: " + url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onAcceptUrl(String url) throws ParsingException {
|
||||||
|
return url.startsWith("https://api.media.ccc.de/public/conferences/")
|
||||||
|
|| url.startsWith("https://media.ccc.de/c/");
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,12 +11,12 @@ public class MediaCCCSearchQueryHandlerFactory extends SearchQueryHandlerFactory
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getAvailableContentFilter() {
|
public String[] getAvailableContentFilter() {
|
||||||
return null;
|
return new String[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getAvailableSortFilter() {
|
public String[] getAvailableSortFilter() {
|
||||||
return null;
|
return new String[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package org.schabi.newpipe.extractor.services.media_ccc.linkHandler;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
|
import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory;
|
||||||
|
|
||||||
|
public class MediaCCCStreamLinkHandlerFactory extends LinkHandlerFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId(String url) throws ParsingException {
|
||||||
|
if(url.startsWith("https://api.media.ccc.de/public/events/") &&
|
||||||
|
!url.contains("?q=")) {
|
||||||
|
return url.replace("https://api.media.ccc.de/public/events/", "");
|
||||||
|
}
|
||||||
|
throw new ParsingException("Could not get id from url: " + url);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUrl(String id) throws ParsingException {
|
||||||
|
return "https://api.media.ccc.de/public/events/" + id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onAcceptUrl(String url) throws ParsingException {
|
||||||
|
return url.startsWith("https://api.media.ccc.de/public/events/") &&
|
||||||
|
!url.contains("?q=");
|
||||||
|
}
|
||||||
|
}
|
|
@ -127,9 +127,4 @@ public class SoundcloudChannelExtractor extends ChannelExtractor {
|
||||||
|
|
||||||
return new InfoItemsPage<>(collector, nextPageUrl);
|
return new InfoItemsPage<>(collector, nextPageUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getDonationLinks() {
|
|
||||||
return new String[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,29 +189,6 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
|
||||||
return new InfoItemsPage<>(collector, getNextPageUrlFromAjaxPage(ajaxJson, pageUrl));
|
return new InfoItemsPage<>(collector, getNextPageUrlFromAjaxPage(ajaxJson, pageUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getDonationLinks() throws ParsingException {
|
|
||||||
try {
|
|
||||||
ArrayList<String> links = new ArrayList<>();
|
|
||||||
Element linkHolder = doc.select("div[id=\"header-links\"]").first();
|
|
||||||
if(linkHolder == null) {
|
|
||||||
// this occures if no links are embeded into the channel
|
|
||||||
return new String[0];
|
|
||||||
}
|
|
||||||
for(Element a : linkHolder.select("a")) {
|
|
||||||
String link = a.attr("abs:href");
|
|
||||||
if(DonationLinkHelper.getDonatoinServiceByLink(link) != DonationLinkHelper.DonationService.NO_DONATION) {
|
|
||||||
links.add(link);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String[] retLinks = new String[links.size()];
|
|
||||||
retLinks = links.toArray(retLinks);
|
|
||||||
return retLinks;
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new ParsingException("Could not get donation links", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getNextPageUrlFromAjaxPage(final JsonObject ajaxJson, final String pageUrl)
|
private String getNextPageUrlFromAjaxPage(final JsonObject ajaxJson, final String pageUrl)
|
||||||
throws ParsingException {
|
throws ParsingException {
|
||||||
String loadMoreHtmlDataRaw = ajaxJson.getString("load_more_widget_html");
|
String loadMoreHtmlDataRaw = ajaxJson.getString("load_more_widget_html");
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
package org.schabi.newpipe.extractor.services.media_ccc;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.schabi.newpipe.Downloader;
|
||||||
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
|
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCConferenceExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.utils.Localization;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
import static org.schabi.newpipe.extractor.ServiceList.MediaCCC;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test {@link MediaCCCConferenceExtractor}
|
||||||
|
*/
|
||||||
|
public class MediaCCCConferenceExtractorTest {
|
||||||
|
private static ChannelExtractor extractor;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpClass() throws Exception {
|
||||||
|
NewPipe.init(Downloader.getInstance(), new Localization("en", "en_GB"));
|
||||||
|
extractor = MediaCCC.getChannelExtractor("https://api.media.ccc.de/public/conferences/froscon2017");
|
||||||
|
extractor.fetchPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testName() throws Exception {
|
||||||
|
assertEquals("FrOSCon 2017", extractor.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetUrl() throws Exception {
|
||||||
|
assertEquals("https://api.media.ccc.de/public/conferences/froscon2017", extractor.getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetOriginalUrl() throws Exception {
|
||||||
|
assertEquals("https://media.ccc.de/c/froscon2017", extractor.getOriginalUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetThumbnailUrl() throws Exception {
|
||||||
|
assertEquals("https://static.media.ccc.de/media/events/froscon/2017/logo.png", extractor.getAvatarUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetInitalPage() throws Exception {
|
||||||
|
assertEquals(97,extractor.getInitialPage().getItems().size());
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,7 +10,9 @@ import org.schabi.newpipe.extractor.search.SearchExtractor;
|
||||||
import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCSearchExtractor;
|
import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCSearchExtractor;
|
||||||
import org.schabi.newpipe.extractor.utils.Localization;
|
import org.schabi.newpipe.extractor.utils.Localization;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
import static junit.framework.TestCase.assertTrue;
|
import static junit.framework.TestCase.assertTrue;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.schabi.newpipe.extractor.ServiceList.MediaCCC;
|
import static org.schabi.newpipe.extractor.ServiceList.MediaCCC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,4 +35,27 @@ public class MediaCCCSearchExtractorTest {
|
||||||
assertTrue(Integer.toString(itemsPage.getItems().size()),
|
assertTrue(Integer.toString(itemsPage.getItems().size()),
|
||||||
itemsPage.getItems().size() >= 25);
|
itemsPage.getItems().size() >= 25);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testServiceId() throws Exception {
|
||||||
|
assertEquals(2, extractor.getServiceId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testName() throws Exception {
|
||||||
|
assertFalse(itemsPage.getItems().get(0).getName(), itemsPage.getItems().get(0).getName().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUrl() throws Exception {
|
||||||
|
assertTrue("Url should start with: https://api.media.ccc.de/public/events/",
|
||||||
|
itemsPage.getItems().get(0).getUrl().startsWith("https://api.media.ccc.de/public/events/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testThumbnailUrl() throws Exception {
|
||||||
|
assertTrue(itemsPage.getItems().get(0).getThumbnailUrl(),
|
||||||
|
itemsPage.getItems().get(0).getThumbnailUrl().startsWith("https://static.media.ccc.de/media/")
|
||||||
|
&& itemsPage.getItems().get(0).getThumbnailUrl().endsWith(".jpg"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
package org.schabi.newpipe.extractor.services.media_ccc;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.schabi.newpipe.Downloader;
|
||||||
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
|
import org.schabi.newpipe.extractor.services.BaseExtractorTest;
|
||||||
|
import org.schabi.newpipe.extractor.stream.StreamExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCStreamExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.utils.Localization;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
import static org.schabi.newpipe.extractor.ServiceList.MediaCCC;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test {@link MediaCCCStreamExtractor}
|
||||||
|
*/
|
||||||
|
public class MediaCCCStreamExtractorTest implements BaseExtractorTest {
|
||||||
|
private static StreamExtractor extractor;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpClass() throws Exception {
|
||||||
|
NewPipe.init(Downloader.getInstance(), new Localization("GB", "en"));
|
||||||
|
|
||||||
|
extractor = MediaCCC.getStreamExtractor("https://api.media.ccc.de/public/events/8afc16c2-d76a-53f6-85e4-90494665835d");
|
||||||
|
extractor.fetchPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testServiceId() throws Exception {
|
||||||
|
assertEquals(2, extractor.getServiceId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testName() throws Exception {
|
||||||
|
assertEquals("tmux - Warum ein schwarzes Fenster am Bildschirm reicht", extractor.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testId() throws Exception {
|
||||||
|
assertEquals("", extractor.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testUrl() throws Exception {
|
||||||
|
assertEquals("", extractor.getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testOriginalUrl() throws Exception {
|
||||||
|
assertEquals("", extractor.getOriginalUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testThumbnail() throws Exception {
|
||||||
|
assertEquals("https://static.media.ccc.de/media/events/gpn/gpn18/105-hd.jpg", extractor.getThumbnailUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUploaderName() throws Exception {
|
||||||
|
assertEquals("gpn18", extractor.getUploaderName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUploaderUrl() throws Exception {
|
||||||
|
assertEquals("https://api.media.ccc.de/public/conferences/gpn18", extractor.getUploaderUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUploaderAvatarUrl() throws Exception {
|
||||||
|
assertEquals("https://static.media.ccc.de/media/events/gpn/gpn18/logo.png", extractor.getUploaderAvatarUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVideoStreams() throws Exception {
|
||||||
|
assertEquals(4, extractor.getVideoStreams().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAudioStreams() throws Exception {
|
||||||
|
assertEquals(2, extractor.getAudioStreams().size());
|
||||||
|
}
|
||||||
|
}
|
|
@ -106,13 +106,6 @@ public class YoutubeChannelExtractorTest {
|
||||||
public void testSubscriberCount() throws Exception {
|
public void testSubscriberCount() throws Exception {
|
||||||
assertTrue("Wrong subscriber count", extractor.getSubscriberCount() >= 0);
|
assertTrue("Wrong subscriber count", extractor.getSubscriberCount() >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testChannelDonation() throws Exception {
|
|
||||||
// this needs to be ignored since wed have to upgrade channel extractor to the new yt interface
|
|
||||||
// in order to make this work
|
|
||||||
assertTrue(extractor.getDonationLinks().length == 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Youtube RED/Premium ad blocking test
|
// Youtube RED/Premium ad blocking test
|
||||||
|
@ -204,12 +197,6 @@ public class YoutubeChannelExtractorTest {
|
||||||
assertTrue("Wrong subscriber count", extractor.getSubscriberCount() >= 0);
|
assertTrue("Wrong subscriber count", extractor.getSubscriberCount() >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testChannelDonation() throws Exception {
|
|
||||||
// this needs to be ignored since wed have to upgrade channel extractor to the new yt interface
|
|
||||||
// in order to make this work
|
|
||||||
assertTrue(extractor.getDonationLinks().length == 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Kurzgesagt implements BaseChannelExtractorTest {
|
public static class Kurzgesagt implements BaseChannelExtractorTest {
|
||||||
|
@ -312,11 +299,6 @@ public class YoutubeChannelExtractorTest {
|
||||||
public void testSubscriberCount() throws Exception {
|
public void testSubscriberCount() throws Exception {
|
||||||
assertTrue("Wrong subscriber count", extractor.getSubscriberCount() >= 5e6);
|
assertTrue("Wrong subscriber count", extractor.getSubscriberCount() >= 5e6);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testChannelDonation() throws Exception {
|
|
||||||
assertTrue(extractor.getDonationLinks().length == 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CaptainDisillusion implements BaseChannelExtractorTest {
|
public static class CaptainDisillusion implements BaseChannelExtractorTest {
|
||||||
|
@ -501,11 +483,6 @@ public class YoutubeChannelExtractorTest {
|
||||||
public void testSubscriberCount() throws Exception {
|
public void testSubscriberCount() throws Exception {
|
||||||
assertTrue("Wrong subscriber count", extractor.getSubscriberCount() >= 50);
|
assertTrue("Wrong subscriber count", extractor.getSubscriberCount() >= 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testChannelDonation() throws Exception {
|
|
||||||
assertTrue(extractor.getDonationLinks().length == 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import org.schabi.newpipe.Downloader;
|
||||||
import org.schabi.newpipe.extractor.InfoItem;
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.ListExtractor;
|
import org.schabi.newpipe.extractor.ListExtractor;
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
|
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
||||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
||||||
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeSearchExtractor;
|
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeSearchExtractor;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||||
|
@ -63,13 +64,16 @@ public class YoutubeSearchExtractorDefaultTest extends YoutubeSearchExtractorBas
|
||||||
@Test
|
@Test
|
||||||
public void testResultList_FirstElement() {
|
public void testResultList_FirstElement() {
|
||||||
InfoItem firstInfoItem = itemsPage.getItems().get(0);
|
InfoItem firstInfoItem = itemsPage.getItems().get(0);
|
||||||
if(! (firstInfoItem instanceof ChannelInfoItem))
|
InfoItem secondInfoItem = itemsPage.getItems().get(1);
|
||||||
firstInfoItem = itemsPage.getItems().get(1);
|
|
||||||
|
InfoItem channelItem = firstInfoItem instanceof ChannelInfoItem ? firstInfoItem
|
||||||
|
: secondInfoItem;
|
||||||
|
|
||||||
// The channel should be the first item
|
// The channel should be the first item
|
||||||
assertTrue(firstInfoItem instanceof ChannelInfoItem);
|
assertTrue((firstInfoItem instanceof ChannelInfoItem)
|
||||||
assertEquals("name", "PewDiePie", firstInfoItem.getName());
|
|| (secondInfoItem instanceof ChannelInfoItem));
|
||||||
assertEquals("url","https://www.youtube.com/user/PewDiePie", firstInfoItem.getUrl());
|
assertEquals("name", "PewDiePie", channelItem.getName());
|
||||||
|
assertEquals("url","https://www.youtube.com/user/PewDiePie", channelItem.getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue