added peertube extractor
This commit is contained in:
parent
e85958b180
commit
20f280cb57
|
@ -117,6 +117,13 @@ public enum MediaFormat {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static MediaFormat getFromSuffix(String suffix) {
|
||||
for (MediaFormat vf: values()) {
|
||||
if (vf.suffix.equals(suffix)) return vf;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the format
|
||||
* @return the name of the format
|
||||
|
@ -140,4 +147,5 @@ public enum MediaFormat {
|
|||
public String getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.schabi.newpipe.extractor;
|
||||
|
||||
import org.schabi.newpipe.extractor.services.peertube.PeertubeService;
|
||||
import org.schabi.newpipe.extractor.services.soundcloud.SoundcloudService;
|
||||
import org.schabi.newpipe.extractor.services.youtube.YoutubeService;
|
||||
|
||||
|
@ -18,11 +19,14 @@ public final class ServiceList {
|
|||
|
||||
public static final YoutubeService YouTube;
|
||||
public static final SoundcloudService SoundCloud;
|
||||
public static final PeertubeService PeerTube;
|
||||
|
||||
private static final List<StreamingService> SERVICES = unmodifiableList(
|
||||
asList(
|
||||
YouTube = new YoutubeService(0),
|
||||
SoundCloud = new SoundcloudService(1)
|
||||
SoundCloud = new SoundcloudService(1),
|
||||
PeerTube = new PeertubeService(2)
|
||||
|
||||
));
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,7 +22,8 @@ import org.schabi.newpipe.extractor.utils.Localization;
|
|||
|
||||
public abstract class StreamingService {
|
||||
public static class ServiceInfo {
|
||||
private final String name;
|
||||
private String name;
|
||||
|
||||
private final List<MediaCapability> mediaCapabilities;
|
||||
|
||||
public ServiceInfo(String name, List<MediaCapability> mediaCapabilities) {
|
||||
|
@ -33,6 +34,10 @@ public abstract class StreamingService {
|
|||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<MediaCapability> getMediaCapabilities() {
|
||||
return mediaCapabilities;
|
||||
|
@ -191,6 +196,8 @@ public abstract class StreamingService {
|
|||
}
|
||||
|
||||
public abstract boolean isCommentsSupported();
|
||||
|
||||
public abstract String getBaseUrl();
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jsoup.helper.StringUtil;
|
||||
import org.schabi.newpipe.extractor.DownloadResponse;
|
||||
import org.schabi.newpipe.extractor.Downloader;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
|
||||
import org.schabi.newpipe.extractor.utils.JsonUtils;
|
||||
|
||||
import com.grack.nanojson.JsonObject;
|
||||
import com.grack.nanojson.JsonParser;
|
||||
import com.grack.nanojson.JsonParserException;
|
||||
|
||||
public class PeertubeInstance {
|
||||
|
||||
private final String url;
|
||||
private String name;
|
||||
public static final PeertubeInstance defaultInstance = new PeertubeInstance("https://peertube.mastodon.host", "PeerTube on Mastodon.host");
|
||||
|
||||
public PeertubeInstance(String url) throws IOException {
|
||||
this.url = url;
|
||||
String response = validateInstance(url);
|
||||
setInstanceMetaData(response);
|
||||
}
|
||||
|
||||
private PeertubeInstance(String url , String name) {
|
||||
this.url = url;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
private String validateInstance(String url) throws IOException {
|
||||
Downloader downloader = NewPipe.getDownloader();
|
||||
DownloadResponse response = null;
|
||||
|
||||
try {
|
||||
response = downloader.get(url + "/api/v1/config");
|
||||
} catch (ReCaptchaException | IOException e) {
|
||||
throw new IOException("unable to configure instance " + url, e);
|
||||
}
|
||||
|
||||
if(null == response || StringUtil.isBlank(response.getResponseBody())) {
|
||||
throw new IOException("unable to configure instance " + url);
|
||||
}
|
||||
|
||||
return response.getResponseBody();
|
||||
}
|
||||
|
||||
private void setInstanceMetaData(String responseBody) {
|
||||
JsonObject json;
|
||||
try {
|
||||
json = JsonParser.object().from(responseBody);
|
||||
} catch (JsonParserException e) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(null == json) return;
|
||||
|
||||
try {
|
||||
this.name = JsonUtils.getString(json, "instance.name");
|
||||
} catch (ParsingException e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
|
||||
public class PeertubeParsingHelper {
|
||||
|
||||
private PeertubeParsingHelper() {
|
||||
}
|
||||
|
||||
public static String toDateString(String time) throws ParsingException {
|
||||
try {
|
||||
Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S'Z'").parse(time);
|
||||
SimpleDateFormat newDateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
return newDateFormat.format(date);
|
||||
} catch (ParseException e) {
|
||||
throw new ParsingException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.VIDEO;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.jsoup.helper.StringUtil;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability;
|
||||
import org.schabi.newpipe.extractor.SuggestionExtractor;
|
||||
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
||||
import org.schabi.newpipe.extractor.comments.CommentsExtractor;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.kiosk.KioskExtractor;
|
||||
import org.schabi.newpipe.extractor.kiosk.KioskList;
|
||||
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.SearchQueryHandler;
|
||||
import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.playlist.PlaylistExtractor;
|
||||
import org.schabi.newpipe.extractor.search.SearchExtractor;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeChannelExtractor;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeCommentsExtractor;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeSearchExtractor;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeStreamExtractor;
|
||||
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.PeertubeCommentsLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeSearchQueryHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeStreamLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeTrendingLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.stream.StreamExtractor;
|
||||
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
|
||||
public class PeertubeService extends StreamingService {
|
||||
|
||||
private PeertubeInstance instance;
|
||||
|
||||
public PeertubeService(int id) {
|
||||
this(id, PeertubeInstance.defaultInstance);
|
||||
}
|
||||
|
||||
public PeertubeService(int id, PeertubeInstance instance) {
|
||||
super(id, instance.getName(), singletonList(VIDEO));
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public PeertubeService(int id, String name, List<MediaCapability> capabilities) {
|
||||
super(id, name, capabilities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinkHandlerFactory getStreamLHFactory() {
|
||||
return PeertubeStreamLinkHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getChannelLHFactory() {
|
||||
return PeertubeChannelLinkHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getPlaylistLHFactory() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchQueryHandlerFactory getSearchQHFactory() {
|
||||
return PeertubeSearchQueryHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListLinkHandlerFactory getCommentsLHFactory() {
|
||||
return PeertubeCommentsLinkHandlerFactory.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchExtractor getSearchExtractor(SearchQueryHandler queryHandler, Localization localization) {
|
||||
return new PeertubeSearchExtractor(this, queryHandler, localization);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SuggestionExtractor getSuggestionExtractor(Localization localization) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubscriptionExtractor getSubscriptionExtractor() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KioskList getKioskList(Localization localization) throws ExtractionException {
|
||||
KioskList.KioskExtractorFactory kioskFactory = new KioskList.KioskExtractorFactory() {
|
||||
@Override
|
||||
public KioskExtractor createNewKiosk(StreamingService streamingService,
|
||||
String url,
|
||||
String id,
|
||||
Localization local)
|
||||
throws ExtractionException {
|
||||
return new PeertubeTrendingExtractor(PeertubeService.this,
|
||||
new PeertubeTrendingLinkHandlerFactory().fromId(id), id, local);
|
||||
}
|
||||
};
|
||||
|
||||
KioskList list = new KioskList(getServiceId(), localization);
|
||||
|
||||
// add kiosks here e.g.:
|
||||
final PeertubeTrendingLinkHandlerFactory h = new PeertubeTrendingLinkHandlerFactory();
|
||||
try {
|
||||
list.addKioskEntry(kioskFactory, h, PeertubeTrendingLinkHandlerFactory.KIOSK_TRENDING);
|
||||
list.addKioskEntry(kioskFactory, h, PeertubeTrendingLinkHandlerFactory.KIOSK_RECENT);
|
||||
list.addKioskEntry(kioskFactory, h, PeertubeTrendingLinkHandlerFactory.KIOSK_LOCAL);
|
||||
list.setDefaultKiosk(PeertubeTrendingLinkHandlerFactory.KIOSK_TRENDING);
|
||||
} catch (Exception e) {
|
||||
throw new ExtractionException(e);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelExtractor getChannelExtractor(ListLinkHandler linkHandler, Localization localization)
|
||||
throws ExtractionException {
|
||||
return new PeertubeChannelExtractor(this, linkHandler, localization);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlaylistExtractor getPlaylistExtractor(ListLinkHandler linkHandler, Localization localization)
|
||||
throws ExtractionException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamExtractor getStreamExtractor(LinkHandler linkHandler, Localization localization)
|
||||
throws ExtractionException {
|
||||
return new PeertubeStreamExtractor(this, linkHandler, localization);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommentsExtractor getCommentsExtractor(ListLinkHandler linkHandler, Localization localization)
|
||||
throws ExtractionException {
|
||||
return new PeertubeCommentsExtractor(this, linkHandler, localization);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCommentsSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseUrl() {
|
||||
return instance.getUrl();
|
||||
}
|
||||
|
||||
public void setInstance(String url) throws IOException {
|
||||
this.instance = new PeertubeInstance(url);
|
||||
if(!StringUtil.isBlank(instance.getName())) {
|
||||
this.getServiceInfo().setName(instance.getName());
|
||||
}else {
|
||||
this.getServiceInfo().setName("PeerTube");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.extractors;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jsoup.helper.StringUtil;
|
||||
import org.schabi.newpipe.extractor.DownloadResponse;
|
||||
import org.schabi.newpipe.extractor.Downloader;
|
||||
import org.schabi.newpipe.extractor.ServiceList;
|
||||
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.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
||||
import org.schabi.newpipe.extractor.utils.JsonUtils;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
import org.schabi.newpipe.extractor.utils.Parser;
|
||||
import org.schabi.newpipe.extractor.utils.Parser.RegexException;
|
||||
|
||||
import com.grack.nanojson.JsonArray;
|
||||
import com.grack.nanojson.JsonObject;
|
||||
import com.grack.nanojson.JsonParser;
|
||||
import com.grack.nanojson.JsonParserException;
|
||||
|
||||
public class PeertubeChannelExtractor extends ChannelExtractor {
|
||||
|
||||
private static final String START_KEY = "start";
|
||||
private static final String COUNT_KEY = "count";
|
||||
private static final int ITEMS_PER_PAGE = 12;
|
||||
private static final String START_PATTERN = "start=(\\d*)";
|
||||
|
||||
private InfoItemsPage<StreamInfoItem> initPage;
|
||||
private long total;
|
||||
|
||||
private JsonObject json;
|
||||
|
||||
public PeertubeChannelExtractor(StreamingService service, ListLinkHandler linkHandler, Localization localization) {
|
||||
super(service, linkHandler, localization);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAvatarUrl() throws ParsingException {
|
||||
String value = JsonUtils.getString(json, "avatar.path");
|
||||
return ServiceList.PeerTube.getBaseUrl() + value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBannerUrl() throws ParsingException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFeedUrl() throws ParsingException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSubscriberCount() throws ParsingException {
|
||||
Number number = JsonUtils.getNumber(json, "followersCount");
|
||||
return number.longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() throws ParsingException {
|
||||
try {
|
||||
return JsonUtils.getString(json, "description");
|
||||
}catch(ParsingException e) {
|
||||
return "No description";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDonationLinks() throws ParsingException {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemsPage<StreamInfoItem> getInitialPage() throws IOException, ExtractionException {
|
||||
super.fetchPage();
|
||||
return initPage;
|
||||
}
|
||||
|
||||
private void collectStreamsFrom(StreamInfoItemsCollector collector, JsonObject json, String pageUrl) throws ParsingException {
|
||||
JsonArray contents;
|
||||
try {
|
||||
contents = (JsonArray) JsonUtils.getValue(json, "data");
|
||||
}catch(Exception e) {
|
||||
throw new ParsingException("unable to extract channel streams", e);
|
||||
}
|
||||
|
||||
for(Object c: contents) {
|
||||
if(c instanceof JsonObject) {
|
||||
final JsonObject item = (JsonObject) c;
|
||||
PeertubeStreamInfoItemExtractor extractor = new PeertubeStreamInfoItemExtractor(item);
|
||||
collector.commit(extractor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNextPageUrl() throws IOException, ExtractionException {
|
||||
super.fetchPage();
|
||||
return initPage.getNextPageUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemsPage<StreamInfoItem> getPage(String pageUrl) throws IOException, ExtractionException {
|
||||
DownloadResponse response = getDownloader().get(pageUrl);
|
||||
JsonObject json = null;
|
||||
if(null != response && !StringUtil.isBlank(response.getResponseBody())) {
|
||||
try {
|
||||
json = JsonParser.object().from(response.getResponseBody());
|
||||
} catch (Exception e) {
|
||||
throw new ParsingException("Could not parse json data for kiosk info", e);
|
||||
}
|
||||
}
|
||||
|
||||
StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
|
||||
if(json != null) {
|
||||
Number number = JsonUtils.getNumber(json, "total");
|
||||
if(number != null) this.total = number.longValue();
|
||||
collectStreamsFrom(collector, json, pageUrl);
|
||||
} else {
|
||||
throw new ExtractionException("Unable to get peertube kiosk info");
|
||||
}
|
||||
return new InfoItemsPage<>(collector, getNextPageUrl(pageUrl));
|
||||
}
|
||||
|
||||
|
||||
private String getNextPageUrl(String prevPageUrl) {
|
||||
String prevStart;
|
||||
try {
|
||||
prevStart = Parser.matchGroup1(START_PATTERN, prevPageUrl);
|
||||
} catch (RegexException e) {
|
||||
return "";
|
||||
}
|
||||
if(StringUtil.isBlank(prevStart)) return "";
|
||||
long nextStart = 0;
|
||||
try {
|
||||
nextStart = Long.valueOf(prevStart) + ITEMS_PER_PAGE;
|
||||
} catch (NumberFormatException e) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if(nextStart >= total) {
|
||||
return "";
|
||||
}else {
|
||||
return prevPageUrl.replace(START_KEY + "=" + prevStart, START_KEY + "=" + String.valueOf(nextStart));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchPage(Downloader downloader) throws IOException, ExtractionException {
|
||||
DownloadResponse response = downloader.get(getUrl());
|
||||
if(null != response && null != response.getResponseBody()) {
|
||||
setInitialData(response.getResponseBody());
|
||||
}else {
|
||||
throw new ExtractionException("Unable to extract peertube channel data");
|
||||
}
|
||||
|
||||
String pageUrl = getUrl() + "/videos?" + START_KEY + "=0&" + COUNT_KEY + "=" + ITEMS_PER_PAGE;
|
||||
this.initPage = getPage(pageUrl);
|
||||
}
|
||||
|
||||
private void setInitialData(String responseBody) throws ExtractionException {
|
||||
try {
|
||||
json = JsonParser.object().from(responseBody);
|
||||
} catch (JsonParserException e) {
|
||||
throw new ExtractionException("Unable to extract peertube channel data", e);
|
||||
}
|
||||
if(null == json) throw new ExtractionException("Unable to extract peertube channel data");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() throws ParsingException {
|
||||
return JsonUtils.getString(json, "displayName");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.extractors;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jsoup.helper.StringUtil;
|
||||
import org.schabi.newpipe.extractor.DownloadResponse;
|
||||
import org.schabi.newpipe.extractor.Downloader;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.comments.CommentsExtractor;
|
||||
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
|
||||
import org.schabi.newpipe.extractor.comments.CommentsInfoItemsCollector;
|
||||
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.utils.JsonUtils;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
import org.schabi.newpipe.extractor.utils.Parser;
|
||||
import org.schabi.newpipe.extractor.utils.Parser.RegexException;
|
||||
|
||||
import com.grack.nanojson.JsonArray;
|
||||
import com.grack.nanojson.JsonObject;
|
||||
import com.grack.nanojson.JsonParser;
|
||||
|
||||
public class PeertubeCommentsExtractor extends CommentsExtractor {
|
||||
|
||||
private static final String START_KEY = "start";
|
||||
private static final String COUNT_KEY = "count";
|
||||
private static final int ITEMS_PER_PAGE = 12;
|
||||
private static final String START_PATTERN = "start=(\\d*)";
|
||||
|
||||
private InfoItemsPage<CommentsInfoItem> initPage;
|
||||
private long total;
|
||||
|
||||
public PeertubeCommentsExtractor(StreamingService service, ListLinkHandler uiHandler, Localization localization) {
|
||||
super(service, uiHandler, localization);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() throws ParsingException {
|
||||
return "Comments";
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemsPage<CommentsInfoItem> getInitialPage() throws IOException, ExtractionException {
|
||||
super.fetchPage();
|
||||
return initPage;
|
||||
}
|
||||
|
||||
private void collectStreamsFrom(CommentsInfoItemsCollector collector, JsonObject json, String pageUrl) throws ParsingException {
|
||||
JsonArray contents;
|
||||
try {
|
||||
contents = (JsonArray) JsonUtils.getValue(json, "data");
|
||||
}catch(Exception e) {
|
||||
throw new ParsingException("unable to extract comments info", e);
|
||||
}
|
||||
|
||||
for(Object c: contents) {
|
||||
if(c instanceof JsonObject) {
|
||||
final JsonObject item = (JsonObject) c;
|
||||
PeertubeCommentsInfoItemExtractor extractor = new PeertubeCommentsInfoItemExtractor(item, pageUrl);
|
||||
collector.commit(extractor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNextPageUrl() throws IOException, ExtractionException {
|
||||
super.fetchPage();
|
||||
return initPage.getNextPageUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemsPage<CommentsInfoItem> getPage(String pageUrl) throws IOException, ExtractionException {
|
||||
DownloadResponse response = getDownloader().get(pageUrl);
|
||||
JsonObject json = null;
|
||||
if(null != response && !StringUtil.isBlank(response.getResponseBody())) {
|
||||
try {
|
||||
json = JsonParser.object().from(response.getResponseBody());
|
||||
} catch (Exception e) {
|
||||
throw new ParsingException("Could not parse json data for comments info", e);
|
||||
}
|
||||
}
|
||||
|
||||
CommentsInfoItemsCollector collector = new CommentsInfoItemsCollector(getServiceId());
|
||||
if(json != null) {
|
||||
Number number = JsonUtils.getNumber(json, "total");
|
||||
if(number != null) this.total = number.longValue();
|
||||
collectStreamsFrom(collector, json, pageUrl);
|
||||
} else {
|
||||
throw new ExtractionException("Unable to get peertube comments info");
|
||||
}
|
||||
return new InfoItemsPage<>(collector, getNextPageUrl(pageUrl));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchPage(Downloader downloader) throws IOException, ExtractionException {
|
||||
String pageUrl = getUrl() + "?" + START_KEY + "=0&" + COUNT_KEY + "=" + ITEMS_PER_PAGE;
|
||||
this.initPage = getPage(pageUrl);
|
||||
}
|
||||
|
||||
private String getNextPageUrl(String prevPageUrl) {
|
||||
String prevStart;
|
||||
try {
|
||||
prevStart = Parser.matchGroup1(START_PATTERN, prevPageUrl);
|
||||
} catch (RegexException e) {
|
||||
return "";
|
||||
}
|
||||
if(StringUtil.isBlank(prevStart)) return "";
|
||||
long nextStart = 0;
|
||||
try {
|
||||
nextStart = Long.valueOf(prevStart) + ITEMS_PER_PAGE;
|
||||
} catch (NumberFormatException e) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if(nextStart >= total) {
|
||||
return "";
|
||||
}else {
|
||||
return prevPageUrl.replace(START_KEY + "=" + prevStart, START_KEY + "=" + String.valueOf(nextStart));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.extractors;
|
||||
|
||||
import org.schabi.newpipe.extractor.ServiceList;
|
||||
import org.schabi.newpipe.extractor.comments.CommentsInfoItemExtractor;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.utils.JsonUtils;
|
||||
|
||||
import com.grack.nanojson.JsonObject;
|
||||
|
||||
|
||||
public class PeertubeCommentsInfoItemExtractor implements CommentsInfoItemExtractor {
|
||||
|
||||
private final JsonObject item;
|
||||
private final String url;
|
||||
|
||||
public PeertubeCommentsInfoItemExtractor(JsonObject item, String url) {
|
||||
this.item = item;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl() throws ParsingException {
|
||||
return url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getThumbnailUrl() throws ParsingException {
|
||||
String value;
|
||||
try {
|
||||
value = JsonUtils.getString(item, "account.avatar.path");
|
||||
}catch(Exception e) {
|
||||
value = "/client/assets/images/default-avatar.png";
|
||||
}
|
||||
return ServiceList.PeerTube.getBaseUrl() + value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() throws ParsingException {
|
||||
return JsonUtils.getString(item, "account.displayName");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPublishedTime() throws ParsingException {
|
||||
return JsonUtils.getString(item, "createdAt");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getLikeCount() throws ParsingException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommentText() throws ParsingException {
|
||||
String htmlText = JsonUtils.getString(item, "text");
|
||||
return htmlText.replaceAll("(?s)<[^>]*>(\\s*<[^>]*>)*", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommentId() throws ParsingException {
|
||||
Number value = JsonUtils.getNumber(item, "id");
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthorThumbnail() throws ParsingException {
|
||||
String value;
|
||||
try {
|
||||
value = JsonUtils.getString(item, "account.avatar.path");
|
||||
}catch(Exception e) {
|
||||
value = "/client/assets/images/default-avatar.png";
|
||||
}
|
||||
return ServiceList.PeerTube.getBaseUrl() + value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthorName() throws ParsingException {
|
||||
return JsonUtils.getString(item, "account.displayName");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthorEndpoint() throws ParsingException {
|
||||
String name = JsonUtils.getString(item, "account.name");
|
||||
String host = JsonUtils.getString(item, "account.host");
|
||||
return PeertubeChannelLinkHandlerFactory.getInstance().fromId(name + "@" + host).getUrl();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.extractors;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.schabi.newpipe.extractor.Downloader;
|
||||
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.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.playlist.PlaylistExtractor;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
|
||||
public class PeertubePlaylistExtractor extends PlaylistExtractor{
|
||||
|
||||
public PeertubePlaylistExtractor(StreamingService service, ListLinkHandler linkHandler, Localization localization) {
|
||||
super(service, linkHandler, localization);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getThumbnailUrl() throws ParsingException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBannerUrl() throws ParsingException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUploaderUrl() throws ParsingException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUploaderName() throws ParsingException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUploaderAvatarUrl() throws ParsingException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStreamCount() throws ParsingException {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemsPage<StreamInfoItem> getInitialPage() throws IOException, ExtractionException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNextPageUrl() throws IOException, ExtractionException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemsPage<StreamInfoItem> getPage(String pageUrl) throws IOException, ExtractionException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchPage(Downloader downloader) throws IOException, ExtractionException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() throws ParsingException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.extractors;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jsoup.helper.StringUtil;
|
||||
import org.schabi.newpipe.extractor.DownloadResponse;
|
||||
import org.schabi.newpipe.extractor.Downloader;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.InfoItemExtractor;
|
||||
import org.schabi.newpipe.extractor.InfoItemsCollector;
|
||||
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.SearchQueryHandler;
|
||||
import org.schabi.newpipe.extractor.search.InfoItemsSearchCollector;
|
||||
import org.schabi.newpipe.extractor.search.SearchExtractor;
|
||||
import org.schabi.newpipe.extractor.utils.JsonUtils;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
import org.schabi.newpipe.extractor.utils.Parser;
|
||||
import org.schabi.newpipe.extractor.utils.Parser.RegexException;
|
||||
|
||||
import com.grack.nanojson.JsonArray;
|
||||
import com.grack.nanojson.JsonObject;
|
||||
import com.grack.nanojson.JsonParser;
|
||||
|
||||
public class PeertubeSearchExtractor extends SearchExtractor {
|
||||
|
||||
private static final String START_KEY = "start";
|
||||
private static final String COUNT_KEY = "count";
|
||||
private static final int ITEMS_PER_PAGE = 12;
|
||||
private static final String START_PATTERN = "start=(\\d*)";
|
||||
|
||||
private InfoItemsPage<InfoItem> initPage;
|
||||
private long total;
|
||||
|
||||
public PeertubeSearchExtractor(StreamingService service, SearchQueryHandler linkHandler,
|
||||
Localization localization) {
|
||||
super(service, linkHandler, localization);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSearchSuggestion() throws ParsingException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemsPage<InfoItem> getInitialPage() throws IOException, ExtractionException {
|
||||
super.fetchPage();
|
||||
return initPage;
|
||||
}
|
||||
|
||||
private InfoItemsCollector<InfoItem, InfoItemExtractor> collectStreamsFrom(JsonObject json) throws ParsingException {
|
||||
|
||||
final InfoItemsSearchCollector collector = getInfoItemSearchCollector();
|
||||
|
||||
JsonArray contents;
|
||||
try {
|
||||
contents = (JsonArray) JsonUtils.getValue(json, "data");
|
||||
}catch(Exception e) {
|
||||
throw new ParsingException("unable to extract search info", e);
|
||||
}
|
||||
|
||||
for(Object c: contents) {
|
||||
if(c instanceof JsonObject) {
|
||||
final JsonObject item = (JsonObject) c;
|
||||
PeertubeStreamInfoItemExtractor extractor = new PeertubeStreamInfoItemExtractor(item);
|
||||
collector.commit(extractor);
|
||||
}
|
||||
}
|
||||
|
||||
return collector;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNextPageUrl() throws IOException, ExtractionException {
|
||||
super.fetchPage();
|
||||
return initPage.getNextPageUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemsPage<InfoItem> getPage(String pageUrl) throws IOException, ExtractionException {
|
||||
DownloadResponse response = getDownloader().get(pageUrl);
|
||||
JsonObject json = null;
|
||||
if(null != response && !StringUtil.isBlank(response.getResponseBody())) {
|
||||
try {
|
||||
json = JsonParser.object().from(response.getResponseBody());
|
||||
} catch (Exception e) {
|
||||
throw new ParsingException("Could not parse json data for search info", e);
|
||||
}
|
||||
}
|
||||
|
||||
if(json != null) {
|
||||
Number number = JsonUtils.getNumber(json, "total");
|
||||
if(number != null) this.total = number.longValue();
|
||||
return new InfoItemsPage<>(collectStreamsFrom(json), getNextPageUrl(pageUrl));
|
||||
} else {
|
||||
throw new ExtractionException("Unable to get peertube search info");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchPage(Downloader downloader) throws IOException, ExtractionException {
|
||||
String pageUrl = getUrl() + "&" + START_KEY + "=0&" + COUNT_KEY + "=" + ITEMS_PER_PAGE;
|
||||
this.initPage = getPage(pageUrl);
|
||||
}
|
||||
|
||||
private String getNextPageUrl(String prevPageUrl) {
|
||||
String prevStart;
|
||||
try {
|
||||
prevStart = Parser.matchGroup1(START_PATTERN, prevPageUrl);
|
||||
} catch (RegexException e) {
|
||||
return "";
|
||||
}
|
||||
if(StringUtil.isBlank(prevStart)) return "";
|
||||
long nextStart = 0;
|
||||
try {
|
||||
nextStart = Long.valueOf(prevStart) + ITEMS_PER_PAGE;
|
||||
} catch (NumberFormatException e) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if(nextStart >= total) {
|
||||
return "";
|
||||
}else {
|
||||
return prevPageUrl.replace(START_KEY + "=" + prevStart, START_KEY + "=" + String.valueOf(nextStart));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,260 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.extractors;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jsoup.helper.StringUtil;
|
||||
import org.schabi.newpipe.extractor.DownloadResponse;
|
||||
import org.schabi.newpipe.extractor.Downloader;
|
||||
import org.schabi.newpipe.extractor.MediaFormat;
|
||||
import org.schabi.newpipe.extractor.ServiceList;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.Subtitles;
|
||||
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.LinkHandler;
|
||||
import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeTrendingLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.soundcloud.SoundcloudParsingHelper;
|
||||
import org.schabi.newpipe.extractor.services.youtube.ItagItem;
|
||||
import org.schabi.newpipe.extractor.stream.AudioStream;
|
||||
import org.schabi.newpipe.extractor.stream.Stream;
|
||||
import org.schabi.newpipe.extractor.stream.StreamExtractor;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
||||
import org.schabi.newpipe.extractor.stream.StreamType;
|
||||
import org.schabi.newpipe.extractor.stream.SubtitlesFormat;
|
||||
import org.schabi.newpipe.extractor.stream.VideoStream;
|
||||
import org.schabi.newpipe.extractor.utils.JsonUtils;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
|
||||
import com.grack.nanojson.JsonArray;
|
||||
import com.grack.nanojson.JsonObject;
|
||||
import com.grack.nanojson.JsonParser;
|
||||
import com.grack.nanojson.JsonParserException;
|
||||
|
||||
public class PeertubeStreamExtractor extends StreamExtractor {
|
||||
|
||||
|
||||
private JsonObject json;
|
||||
|
||||
public PeertubeStreamExtractor(StreamingService service, LinkHandler linkHandler, Localization localization) {
|
||||
super(service, linkHandler, localization);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUploadDate() throws ParsingException {
|
||||
String date = JsonUtils.getString(json, "publishedAt");
|
||||
return PeertubeParsingHelper.toDateString(date);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getThumbnailUrl() throws ParsingException {
|
||||
return ServiceList.PeerTube.getBaseUrl() + JsonUtils.getString(json, "thumbnailPath");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() throws ParsingException {
|
||||
return JsonUtils.getString(json, "description");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAgeLimit() throws ParsingException {
|
||||
return NO_AGE_LIMIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength() throws ParsingException {
|
||||
Number value = JsonUtils.getNumber(json, "duration");
|
||||
return value.longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTimeStamp() throws ParsingException {
|
||||
//TODO fetch timestamp from url if present;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getViewCount() throws ParsingException {
|
||||
Number value = JsonUtils.getNumber(json, "views");
|
||||
return value.longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLikeCount() throws ParsingException {
|
||||
Number value = JsonUtils.getNumber(json, "likes");
|
||||
return value.longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDislikeCount() throws ParsingException {
|
||||
Number value = JsonUtils.getNumber(json, "dislikes");
|
||||
return value.longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUploaderUrl() throws ParsingException {
|
||||
String name = JsonUtils.getString(json, "account.name");
|
||||
String host = JsonUtils.getString(json, "account.host");
|
||||
return PeertubeChannelLinkHandlerFactory.getInstance().fromId(name + "@" + host).getUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUploaderName() throws ParsingException {
|
||||
return JsonUtils.getString(json, "account.displayName");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUploaderAvatarUrl() throws ParsingException {
|
||||
String avatarPath = JsonUtils.getString(json, "account.avatar.path");
|
||||
return ServiceList.PeerTube.getBaseUrl() + avatarPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDashMpdUrl() throws ParsingException {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHlsUrl() throws ParsingException {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AudioStream> getAudioStreams() throws IOException, ExtractionException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VideoStream> getVideoStreams() throws IOException, ExtractionException {
|
||||
assertPageFetched();
|
||||
List<VideoStream> videoStreams = new ArrayList<>();
|
||||
try {
|
||||
JsonArray streams = json.getArray("files", new JsonArray());
|
||||
for(Object s: streams) {
|
||||
if(!(s instanceof JsonObject)) continue;
|
||||
JsonObject stream = (JsonObject) s;
|
||||
String url = JsonUtils.getString(stream, "fileUrl");
|
||||
String resolution = JsonUtils.getString(stream, "resolution.label");
|
||||
String extension = url.substring(url.lastIndexOf(".") + 1);
|
||||
MediaFormat format = MediaFormat.getFromSuffix(extension);
|
||||
VideoStream videoStream = new VideoStream(url, format, resolution);
|
||||
if (!Stream.containSimilarStream(videoStream, videoStreams)) {
|
||||
videoStreams.add(videoStream);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ParsingException("Could not get video streams", e);
|
||||
}
|
||||
|
||||
return videoStreams;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<VideoStream> getVideoOnlyStreams() throws IOException, ExtractionException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Subtitles> getSubtitlesDefault() throws IOException, ExtractionException {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Subtitles> getSubtitles(SubtitlesFormat format) throws IOException, ExtractionException {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamType getStreamType() throws ParsingException {
|
||||
return StreamType.VIDEO_STREAM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamInfoItem getNextVideo() throws IOException, ExtractionException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamInfoItemsCollector getRelatedVideos() throws IOException, ExtractionException {
|
||||
StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
|
||||
|
||||
//TODO fetch related videos not trending
|
||||
String apiUrl = new PeertubeTrendingLinkHandlerFactory().getUrl(PeertubeTrendingLinkHandlerFactory.KIOSK_TRENDING);
|
||||
getStreamsFromApi(collector, apiUrl);
|
||||
return collector;
|
||||
}
|
||||
|
||||
private void getStreamsFromApi(StreamInfoItemsCollector collector, String apiUrl) throws ReCaptchaException, IOException, ParsingException {
|
||||
DownloadResponse response = getDownloader().get(apiUrl);
|
||||
JsonObject relatedVideosJson = null;
|
||||
if(null != response && !StringUtil.isBlank(response.getResponseBody())) {
|
||||
try {
|
||||
relatedVideosJson = JsonParser.object().from(response.getResponseBody());
|
||||
} catch (JsonParserException e) {
|
||||
throw new ParsingException("Could not parse json data for related videos", e);
|
||||
}
|
||||
}
|
||||
|
||||
if(relatedVideosJson != null) {
|
||||
collectStreamsFrom(collector, relatedVideosJson);
|
||||
}
|
||||
}
|
||||
|
||||
private void collectStreamsFrom(StreamInfoItemsCollector collector, JsonObject json) throws ParsingException {
|
||||
JsonArray contents;
|
||||
try {
|
||||
contents = (JsonArray) JsonUtils.getValue(json, "data");
|
||||
}catch(Exception e) {
|
||||
throw new ParsingException("unable to extract related videos", e);
|
||||
}
|
||||
|
||||
for(Object c: contents) {
|
||||
if(c instanceof JsonObject) {
|
||||
final JsonObject item = (JsonObject) c;
|
||||
PeertubeStreamInfoItemExtractor extractor = new PeertubeStreamInfoItemExtractor(item);
|
||||
collector.commit(extractor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getErrorMessage() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchPage(Downloader downloader) throws IOException, ExtractionException {
|
||||
DownloadResponse response = downloader.get(getUrl());
|
||||
if(null != response && null != response.getResponseBody()) {
|
||||
setInitialData(response.getResponseBody());
|
||||
}else {
|
||||
throw new ExtractionException("Unable to extract peertube channel data");
|
||||
}
|
||||
}
|
||||
|
||||
private void setInitialData(String responseBody) throws ExtractionException {
|
||||
try {
|
||||
json = JsonParser.object().from(responseBody);
|
||||
} catch (JsonParserException e) {
|
||||
throw new ExtractionException("Unable to extract peertube stream data", e);
|
||||
}
|
||||
if(null == json) throw new ExtractionException("Unable to extract peertube stream data");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() throws ParsingException {
|
||||
return JsonUtils.getString(json, "name");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.extractors;
|
||||
|
||||
import org.schabi.newpipe.extractor.ServiceList;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeStreamLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor;
|
||||
import org.schabi.newpipe.extractor.stream.StreamType;
|
||||
import org.schabi.newpipe.extractor.utils.JsonUtils;
|
||||
|
||||
import com.grack.nanojson.JsonObject;
|
||||
|
||||
public class PeertubeStreamInfoItemExtractor implements StreamInfoItemExtractor {
|
||||
|
||||
protected final JsonObject item;
|
||||
|
||||
public PeertubeStreamInfoItemExtractor(JsonObject item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl() throws ParsingException {
|
||||
String uuid = JsonUtils.getString(item, "uuid");
|
||||
return PeertubeStreamLinkHandlerFactory.getInstance().fromId(uuid).getUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getThumbnailUrl() throws ParsingException {
|
||||
String value = JsonUtils.getString(item, "thumbnailPath");
|
||||
return ServiceList.PeerTube.getBaseUrl() + value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() throws ParsingException {
|
||||
return JsonUtils.getString(item, "name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAd() throws ParsingException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getViewCount() throws ParsingException {
|
||||
Number value = JsonUtils.getNumber(item, "views");
|
||||
return value.longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUploaderUrl() throws ParsingException {
|
||||
String name = JsonUtils.getString(item, "account.name");
|
||||
String host = JsonUtils.getString(item, "account.host");
|
||||
return PeertubeChannelLinkHandlerFactory.getInstance().fromId(name + "@" + host).getUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUploaderName() throws ParsingException {
|
||||
return JsonUtils.getString(item, "account.displayName");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUploadDate() throws ParsingException {
|
||||
String date = JsonUtils.getString(item, "publishedAt");
|
||||
return PeertubeParsingHelper.toDateString(date);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamType getStreamType() throws ParsingException {
|
||||
return StreamType.VIDEO_STREAM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDuration() throws ParsingException {
|
||||
Number value = JsonUtils.getNumber(item, "duration");
|
||||
return value.longValue();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.extractors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
|
||||
|
||||
public class PeertubeSubscriptionExtractor extends SubscriptionExtractor {
|
||||
|
||||
public PeertubeSubscriptionExtractor(StreamingService service, List<ContentSource> supportedSources) {
|
||||
super(service, supportedSources);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRelatedUrl() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.extractors;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.schabi.newpipe.extractor.SuggestionExtractor;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
|
||||
public class PeertubeSuggestionExtractor extends SuggestionExtractor{
|
||||
|
||||
public PeertubeSuggestionExtractor(int serviceId, Localization localization) {
|
||||
super(serviceId, localization);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> suggestionList(String query) throws IOException, ExtractionException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.extractors;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jsoup.helper.StringUtil;
|
||||
import org.schabi.newpipe.extractor.DownloadResponse;
|
||||
import org.schabi.newpipe.extractor.Downloader;
|
||||
import org.schabi.newpipe.extractor.ServiceList;
|
||||
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.kiosk.KioskExtractor;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeStreamLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
||||
import org.schabi.newpipe.extractor.stream.StreamType;
|
||||
import org.schabi.newpipe.extractor.utils.JsonUtils;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
import org.schabi.newpipe.extractor.utils.Parser;
|
||||
import org.schabi.newpipe.extractor.utils.Parser.RegexException;
|
||||
|
||||
import com.grack.nanojson.JsonArray;
|
||||
import com.grack.nanojson.JsonObject;
|
||||
import com.grack.nanojson.JsonParser;
|
||||
|
||||
public class PeertubeTrendingExtractor extends KioskExtractor {
|
||||
|
||||
private static final String START_KEY = "start";
|
||||
private static final String COUNT_KEY = "count";
|
||||
private static final int ITEMS_PER_PAGE = 12;
|
||||
private static final String START_PATTERN = "start=(\\d*)";
|
||||
|
||||
private InfoItemsPage<StreamInfoItem> initPage;
|
||||
private long total;
|
||||
|
||||
public PeertubeTrendingExtractor(StreamingService streamingService, ListLinkHandler linkHandler, String kioskId,
|
||||
Localization localization) {
|
||||
super(streamingService, linkHandler, kioskId, localization);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() throws ParsingException {
|
||||
return getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemsPage<StreamInfoItem> getInitialPage() throws IOException, ExtractionException {
|
||||
super.fetchPage();
|
||||
return initPage;
|
||||
}
|
||||
|
||||
private void collectStreamsFrom(StreamInfoItemsCollector collector, JsonObject json, String pageUrl) throws ParsingException {
|
||||
JsonArray contents;
|
||||
try {
|
||||
contents = (JsonArray) JsonUtils.getValue(json, "data");
|
||||
}catch(Exception e) {
|
||||
throw new ParsingException("unable to extract kiosk info", e);
|
||||
}
|
||||
|
||||
for(Object c: contents) {
|
||||
if(c instanceof JsonObject) {
|
||||
final JsonObject item = (JsonObject) c;
|
||||
PeertubeStreamInfoItemExtractor extractor = new PeertubeStreamInfoItemExtractor(item);
|
||||
collector.commit(extractor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNextPageUrl() throws IOException, ExtractionException {
|
||||
super.fetchPage();
|
||||
return initPage.getNextPageUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemsPage<StreamInfoItem> getPage(String pageUrl) throws IOException, ExtractionException {
|
||||
DownloadResponse response = getDownloader().get(pageUrl);
|
||||
JsonObject json = null;
|
||||
if(null != response && !StringUtil.isBlank(response.getResponseBody())) {
|
||||
try {
|
||||
json = JsonParser.object().from(response.getResponseBody());
|
||||
} catch (Exception e) {
|
||||
throw new ParsingException("Could not parse json data for kiosk info", e);
|
||||
}
|
||||
}
|
||||
|
||||
StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
|
||||
if(json != null) {
|
||||
Number number = JsonUtils.getNumber(json, "total");
|
||||
if(number != null) this.total = number.longValue();
|
||||
collectStreamsFrom(collector, json, pageUrl);
|
||||
} else {
|
||||
throw new ExtractionException("Unable to get peertube kiosk info");
|
||||
}
|
||||
return new InfoItemsPage<>(collector, getNextPageUrl(pageUrl));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchPage(Downloader downloader) throws IOException, ExtractionException {
|
||||
String pageUrl = getUrl() + "&" + START_KEY + "=0&" + COUNT_KEY + "=" + ITEMS_PER_PAGE;
|
||||
this.initPage = getPage(pageUrl);
|
||||
}
|
||||
|
||||
private String getNextPageUrl(String prevPageUrl) {
|
||||
String prevStart;
|
||||
try {
|
||||
prevStart = Parser.matchGroup1(START_PATTERN, prevPageUrl);
|
||||
} catch (RegexException e) {
|
||||
return "";
|
||||
}
|
||||
if(StringUtil.isBlank(prevStart)) return "";
|
||||
long nextStart = 0;
|
||||
try {
|
||||
nextStart = Long.valueOf(prevStart) + ITEMS_PER_PAGE;
|
||||
} catch (NumberFormatException e) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if(nextStart >= total) {
|
||||
return "";
|
||||
}else {
|
||||
return prevPageUrl.replace(START_KEY + "=" + prevStart, START_KEY + "=" + String.valueOf(nextStart));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.linkHandler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.schabi.newpipe.extractor.ServiceList;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.utils.Parser;
|
||||
|
||||
public class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
|
||||
private static final PeertubeChannelLinkHandlerFactory instance = new PeertubeChannelLinkHandlerFactory();
|
||||
private static final String ID_PATTERN = "/accounts/([^/?&#]*)";
|
||||
private static final String ACCOUNTS_ENDPOINT = "/api/v1/accounts/";
|
||||
|
||||
public static PeertubeChannelLinkHandlerFactory getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(String url) throws ParsingException {
|
||||
return Parser.matchGroup1(ID_PATTERN, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(String id, List<String> contentFilters, String searchFilter) {
|
||||
String baseUrl = ServiceList.PeerTube.getBaseUrl();
|
||||
return baseUrl + ACCOUNTS_ENDPOINT + id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onAcceptUrl(String url) {
|
||||
return url.contains("/accounts/");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.linkHandler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.schabi.newpipe.extractor.ServiceList;
|
||||
import org.schabi.newpipe.extractor.exceptions.FoundAdException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.utils.Parser;
|
||||
|
||||
public class PeertubeCommentsLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
|
||||
private static final PeertubeCommentsLinkHandlerFactory instance = new PeertubeCommentsLinkHandlerFactory();
|
||||
private static final String ID_PATTERN = "/videos/(watch/)?([^/?&#]*)";
|
||||
private static final String COMMENTS_ENDPOINT = "/api/v1/videos/%s/comment-threads";
|
||||
|
||||
public static PeertubeCommentsLinkHandlerFactory getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(String id) {
|
||||
String baseUrl = ServiceList.PeerTube.getBaseUrl();
|
||||
return baseUrl + String.format(COMMENTS_ENDPOINT, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(String url) throws ParsingException, IllegalArgumentException {
|
||||
return Parser.matchGroup(ID_PATTERN, url, 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onAcceptUrl(final String url) throws FoundAdException {
|
||||
return url.contains("/videos/");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(String id, List<String> contentFilter, String sortFilter) throws ParsingException {
|
||||
return getUrl(id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.linkHandler;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.schabi.newpipe.extractor.ServiceList;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.utils.Parser;
|
||||
|
||||
public class PeertubePlaylistLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
|
||||
private static final PeertubePlaylistLinkHandlerFactory instance = new PeertubePlaylistLinkHandlerFactory();
|
||||
private static final String ID_PATTERN = "/video-channels/([^/?&#]*)";
|
||||
private static final String VIDEO_CHANNELS_ENDPOINT = "/api/v1/video-channels/";
|
||||
|
||||
public static PeertubePlaylistLinkHandlerFactory getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(String id, List<String> contentFilters, String sortFilter) {
|
||||
String baseUrl = ServiceList.PeerTube.getBaseUrl();
|
||||
return baseUrl + VIDEO_CHANNELS_ENDPOINT + id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(String url) throws ParsingException {
|
||||
return Parser.matchGroup1(ID_PATTERN, url);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onAcceptUrl(final String url) {
|
||||
return url.contains("/video-channels/");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.linkHandler;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.List;
|
||||
|
||||
import org.schabi.newpipe.extractor.ServiceList;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandlerFactory;
|
||||
|
||||
public class PeertubeSearchQueryHandlerFactory extends SearchQueryHandlerFactory {
|
||||
|
||||
public static final String CHARSET_UTF_8 = "UTF-8";
|
||||
public static final String VIDEOS = "videos";
|
||||
private static final String SEARCH_ENDPOINT = "/api/v1/search/videos";
|
||||
|
||||
public static PeertubeSearchQueryHandlerFactory getInstance() {
|
||||
return new PeertubeSearchQueryHandlerFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(String searchString, List<String> contentFilters, String sortFilter) throws ParsingException {
|
||||
String baseUrl = ServiceList.PeerTube.getBaseUrl();
|
||||
try {
|
||||
final String url = baseUrl + SEARCH_ENDPOINT
|
||||
+ "?search=" + URLEncoder.encode(searchString, CHARSET_UTF_8);
|
||||
|
||||
return url;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new ParsingException("Could not encode query", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAvailableContentFilter() {
|
||||
return new String[] { VIDEOS };
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.linkHandler;
|
||||
|
||||
import org.schabi.newpipe.extractor.ServiceList;
|
||||
import org.schabi.newpipe.extractor.exceptions.FoundAdException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.utils.Parser;
|
||||
|
||||
public class PeertubeStreamLinkHandlerFactory extends LinkHandlerFactory {
|
||||
|
||||
private static final PeertubeStreamLinkHandlerFactory instance = new PeertubeStreamLinkHandlerFactory();
|
||||
private static final String ID_PATTERN = "/videos/(watch/)?([^/?&#]*)";
|
||||
private static final String VIDEO_ENDPOINT = "/api/v1/videos/";
|
||||
|
||||
private PeertubeStreamLinkHandlerFactory() {
|
||||
}
|
||||
|
||||
public static PeertubeStreamLinkHandlerFactory getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl(String id) {
|
||||
String baseUrl = ServiceList.PeerTube.getBaseUrl();
|
||||
return baseUrl + VIDEO_ENDPOINT + id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(String url) throws ParsingException, IllegalArgumentException {
|
||||
return Parser.matchGroup(ID_PATTERN, url, 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onAcceptUrl(final String url) throws FoundAdException {
|
||||
return url.contains("/videos/");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.linkHandler;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.schabi.newpipe.extractor.ServiceList;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
||||
|
||||
public class PeertubeTrendingLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||
|
||||
|
||||
public static final Map<String, String> KIOSK_MAP;
|
||||
public static final String KIOSK_TRENDING = "Trending";
|
||||
public static final String KIOSK_RECENT = "Recently added";
|
||||
public static final String KIOSK_LOCAL = "Local";
|
||||
|
||||
static {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put(KIOSK_TRENDING, "%s/api/v1/videos?sort=-views");
|
||||
map.put(KIOSK_RECENT, "%s/api/v1/videos?sort=-publishedAt");
|
||||
map.put(KIOSK_LOCAL, "%s/api/v1/videos?filter=local");
|
||||
KIOSK_MAP = Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
public String getUrl(String id, List<String> contentFilters, String sortFilter) {
|
||||
String baseUrl = ServiceList.PeerTube.getBaseUrl();
|
||||
return String.format(KIOSK_MAP.get(id), baseUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId(String url) throws ParsingException {
|
||||
|
||||
if(url.contains("/videos/trending")) {
|
||||
return KIOSK_TRENDING;
|
||||
}else if(url.contains("/videos/recently-added")) {
|
||||
return KIOSK_RECENT;
|
||||
}else if(url.contains("/videos/local")){
|
||||
return KIOSK_LOCAL;
|
||||
}else {
|
||||
throw new ParsingException("no id found for this url");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onAcceptUrl(final String url) {
|
||||
return url.contains("/videos/trending") || url.contains("/videos/recently-added") || url.contains("/videos/local");
|
||||
}
|
||||
}
|
|
@ -117,5 +117,10 @@ public class SoundcloudService extends StreamingService {
|
|||
public boolean isCommentsSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseUrl() {
|
||||
return "https://soundcloud.com";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -155,4 +155,9 @@ public class YoutubeService extends StreamingService {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseUrl() {
|
||||
return "https://youtube.com";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,6 +28,26 @@ public class JsonUtils {
|
|||
return result;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static String getString(@Nonnull JsonObject object, @Nonnull String path) throws ParsingException{
|
||||
Object value = getValue(object, path);
|
||||
if(value instanceof String) {
|
||||
return (String) getValue(object, path);
|
||||
}else {
|
||||
throw new ParsingException("Unable to get " + path);
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static Number getNumber(@Nonnull JsonObject object, @Nonnull String path) throws ParsingException{
|
||||
Object value = getValue(object, path);
|
||||
if(value instanceof Number) {
|
||||
return (Number) getValue(object, path);
|
||||
}else {
|
||||
throw new ParsingException("Unable to get " + path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nonnull
|
||||
public static List<Object> getValues(@Nonnull JsonArray array, @Nonnull String path) throws ParsingException {
|
||||
|
|
|
@ -0,0 +1,207 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertEmpty;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
|
||||
import static org.schabi.newpipe.extractor.services.DefaultTests.defaultTestGetPageInNewExtractor;
|
||||
import static org.schabi.newpipe.extractor.services.DefaultTests.defaultTestMoreItems;
|
||||
import static org.schabi.newpipe.extractor.services.DefaultTests.defaultTestRelatedItems;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
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.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.services.BaseChannelExtractorTest;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeChannelExtractor;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
|
||||
/**
|
||||
* Test for {@link PeertubeChannelExtractor}
|
||||
*/
|
||||
public class PeertubeChannelExtractorTest {
|
||||
public static class LilUzi implements BaseChannelExtractorTest {
|
||||
private static PeertubeChannelExtractor extractor;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
NewPipe.init(Downloader.getInstance(), new Localization("GB", "en"));
|
||||
extractor = (PeertubeChannelExtractor) PeerTube
|
||||
.getChannelExtractor("https://peertube.mastodon.host/api/v1/accounts/root@tube.openalgeria.org");
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Extractor
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Test
|
||||
public void testServiceId() {
|
||||
assertEquals(PeerTube.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testName() throws ParsingException {
|
||||
assertEquals("Noureddine HADDAG", extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("root@tube.openalgeria.org", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://peertube.mastodon.host/api/v1/accounts/root@tube.openalgeria.org", extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOriginalUrl() throws ParsingException {
|
||||
assertEquals("https://peertube.mastodon.host/api/v1/accounts/root@tube.openalgeria.org", extractor.getOriginalUrl());
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// ListExtractor
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Test
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor, PeerTube.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
defaultTestMoreItems(extractor, PeerTube.getServiceId());
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// ChannelExtractor
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Test
|
||||
public void testDescription() throws ParsingException {
|
||||
assertNotNull(extractor.getDescription());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvatarUrl() throws ParsingException {
|
||||
assertIsSecureUrl(extractor.getAvatarUrl());
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testBannerUrl() throws ParsingException {
|
||||
assertIsSecureUrl(extractor.getBannerUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFeedUrl() throws ParsingException {
|
||||
assertEmpty(extractor.getFeedUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubscriberCount() throws ParsingException {
|
||||
assertTrue("Wrong subscriber count", extractor.getSubscriberCount() >= 5);
|
||||
}
|
||||
}
|
||||
|
||||
public static class DubMatix implements BaseChannelExtractorTest {
|
||||
private static PeertubeChannelExtractor extractor;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
NewPipe.init(Downloader.getInstance(), new Localization("GB", "en"));
|
||||
extractor = (PeertubeChannelExtractor) PeerTube
|
||||
.getChannelExtractor("https://peertube.mastodon.host/accounts/franceinter@tube.kdy.ch");
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Additional Testing
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Test
|
||||
public void testGetPageInNewExtractor() throws Exception {
|
||||
final ChannelExtractor newExtractor = PeerTube.getChannelExtractor(extractor.getUrl());
|
||||
defaultTestGetPageInNewExtractor(extractor, newExtractor, PeerTube.getServiceId());
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Extractor
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Test
|
||||
public void testServiceId() {
|
||||
assertEquals(PeerTube.getServiceId(), extractor.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testName() throws ParsingException {
|
||||
assertEquals("France Inter", extractor.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testId() throws ParsingException {
|
||||
assertEquals("franceinter@tube.kdy.ch", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUrl() throws ParsingException {
|
||||
assertEquals("https://peertube.mastodon.host/api/v1/accounts/franceinter@tube.kdy.ch", extractor.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOriginalUrl() throws ParsingException {
|
||||
assertEquals("https://peertube.mastodon.host/accounts/franceinter@tube.kdy.ch", extractor.getOriginalUrl());
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// ListExtractor
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Test
|
||||
public void testRelatedItems() throws Exception {
|
||||
defaultTestRelatedItems(extractor, PeerTube.getServiceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoreRelatedItems() throws Exception {
|
||||
defaultTestMoreItems(extractor, PeerTube.getServiceId());
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// ChannelExtractor
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Test
|
||||
public void testDescription() throws ParsingException {
|
||||
assertNotNull(extractor.getDescription());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvatarUrl() throws ParsingException {
|
||||
assertIsSecureUrl(extractor.getAvatarUrl());
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testBannerUrl() throws ParsingException {
|
||||
assertIsSecureUrl(extractor.getBannerUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFeedUrl() throws ParsingException {
|
||||
assertEmpty(extractor.getFeedUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubscriberCount() throws ParsingException {
|
||||
assertTrue("Wrong subscriber count", extractor.getSubscriberCount() >= 75);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.schabi.newpipe.Downloader;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
|
||||
/**
|
||||
* Test for {@link PeertubeChannelLinkHandlerFactory}
|
||||
*/
|
||||
public class PeertubeChannelLinkHandlerFactoryTest {
|
||||
|
||||
private static PeertubeChannelLinkHandlerFactory linkHandler;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
linkHandler = PeertubeChannelLinkHandlerFactory.getInstance();
|
||||
NewPipe.init(Downloader.getInstance(), new Localization("GB", "en"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void acceptrUrlTest() throws ParsingException {
|
||||
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/accounts/kranti@videos.squat.net"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIdFromUrl() throws ParsingException {
|
||||
assertEquals("kranti@videos.squat.net", linkHandler.fromUrl("https://peertube.mastodon.host/accounts/kranti@videos.squat.net").getId());
|
||||
assertEquals("kranti@videos.squat.net", linkHandler.fromUrl("https://peertube.mastodon.host/accounts/kranti@videos.squat.net/videos").getId());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.jsoup.helper.StringUtil;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.schabi.newpipe.Downloader;
|
||||
import org.schabi.newpipe.extractor.ListExtractor.InfoItemsPage;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.comments.CommentsInfo;
|
||||
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeCommentsExtractor;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
|
||||
public class PeertubeCommentsExtractorTest {
|
||||
|
||||
private static PeertubeCommentsExtractor extractor;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
NewPipe.init(Downloader.getInstance(), new Localization("GB", "en"));
|
||||
extractor = (PeertubeCommentsExtractor) PeerTube
|
||||
.getCommentsExtractor("https://peertube.mastodon.host/videos/watch/04af977f-4201-4697-be67-a8d8cae6fa7a");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetComments() throws IOException, ExtractionException {
|
||||
boolean result = false;
|
||||
InfoItemsPage<CommentsInfoItem> comments = extractor.getInitialPage();
|
||||
result = findInComments(comments, "@root A great documentary on a great guy.");
|
||||
|
||||
while (comments.hasNextPage() && !result) {
|
||||
comments = extractor.getPage(comments.getNextPageUrl());
|
||||
result = findInComments(comments, "@root A great documentary on a great guy.");
|
||||
}
|
||||
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCommentsFromCommentsInfo() throws IOException, ExtractionException {
|
||||
boolean result = false;
|
||||
CommentsInfo commentsInfo = CommentsInfo.getInfo("https://peertube.mastodon.host/videos/watch/a8ea95b8-0396-49a6-8f30-e25e25fb2828");
|
||||
assertTrue("Comments".equals(commentsInfo.getName()));
|
||||
result = findInComments(commentsInfo.getRelatedItems(), "Loved it!!!");
|
||||
|
||||
String nextPage = commentsInfo.getNextPageUrl();
|
||||
while (!StringUtil.isBlank(nextPage) && !result) {
|
||||
InfoItemsPage<CommentsInfoItem> moreItems = CommentsInfo.getMoreItems(PeerTube, commentsInfo, nextPage);
|
||||
result = findInComments(moreItems.getItems(), "Loved it!!!");
|
||||
nextPage = moreItems.getNextPageUrl();
|
||||
}
|
||||
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCommentsAllData() throws IOException, ExtractionException {
|
||||
InfoItemsPage<CommentsInfoItem> comments = extractor.getInitialPage();
|
||||
for(CommentsInfoItem c: comments.getItems()) {
|
||||
assertFalse(StringUtil.isBlank(c.getAuthorEndpoint()));
|
||||
assertFalse(StringUtil.isBlank(c.getAuthorName()));
|
||||
assertFalse(StringUtil.isBlank(c.getAuthorThumbnail()));
|
||||
assertFalse(StringUtil.isBlank(c.getCommentId()));
|
||||
assertFalse(StringUtil.isBlank(c.getCommentText()));
|
||||
assertFalse(StringUtil.isBlank(c.getName()));
|
||||
assertFalse(StringUtil.isBlank(c.getPublishedTime()));
|
||||
assertFalse(StringUtil.isBlank(c.getThumbnailUrl()));
|
||||
assertFalse(StringUtil.isBlank(c.getUrl()));
|
||||
assertFalse(c.getLikeCount() == null);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean findInComments(InfoItemsPage<CommentsInfoItem> comments, String comment) {
|
||||
return findInComments(comments.getItems(), comment);
|
||||
}
|
||||
|
||||
private boolean findInComments(List<CommentsInfoItem> comments, String comment) {
|
||||
for(CommentsInfoItem c: comments) {
|
||||
if(c.getCommentText().contains(comment)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.schabi.newpipe.Downloader;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeCommentsLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
|
||||
/**
|
||||
* Test for {@link PeertubeCommentsLinkHandlerFactory}
|
||||
*/
|
||||
public class PeertubeCommentsLinkHandlerFactoryTest {
|
||||
|
||||
private static PeertubeCommentsLinkHandlerFactory linkHandler;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
linkHandler = PeertubeCommentsLinkHandlerFactory.getInstance();
|
||||
NewPipe.init(Downloader.getInstance(), new Localization("GB", "en"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void acceptrUrlTest() throws ParsingException {
|
||||
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/api/v1/videos/19319/comment-threads?start=0&count=10&sort=-createdAt"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIdFromUrl() throws ParsingException {
|
||||
assertEquals("19319", linkHandler.fromUrl("https://peertube.mastodon.host/api/v1/videos/19319/comment-threads").getId());
|
||||
assertEquals("19319", linkHandler.fromUrl("https://peertube.mastodon.host/api/v1/videos/19319/comment-threads?start=0&count=10&sort=-createdAt").getId());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.schabi.newpipe.Downloader;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubePlaylistLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
|
||||
/**
|
||||
* Test for {@link PeertubePlaylistLinkHandlerFactory}
|
||||
*/
|
||||
public class PeertubePlaylistLinkHandlerFactoryTest {
|
||||
|
||||
private static PeertubePlaylistLinkHandlerFactory linkHandler;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
linkHandler = PeertubePlaylistLinkHandlerFactory.getInstance();
|
||||
NewPipe.init(Downloader.getInstance(), new Localization("GB", "en"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void acceptrUrlTest() throws ParsingException {
|
||||
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/video-channels/b45e84fb-c47f-475b-94f2-718126154d33/videos"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIdFromUrl() throws ParsingException {
|
||||
assertEquals("b45e84fb-c47f-475b-94f2-718126154d33", linkHandler.fromUrl("https://peertube.mastodon.host/video-channels/b45e84fb-c47f-475b-94f2-718126154d33").getId());
|
||||
assertEquals("b45e84fb-c47f-475b-94f2-718126154d33", linkHandler.fromUrl("https://peertube.mastodon.host/video-channels/b45e84fb-c47f-475b-94f2-718126154d33/videos").getId());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.schabi.newpipe.Downloader;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeStreamExtractor;
|
||||
import org.schabi.newpipe.extractor.stream.StreamExtractor;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
||||
import org.schabi.newpipe.extractor.stream.StreamType;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
|
||||
|
||||
/**
|
||||
* Test for {@link StreamExtractor}
|
||||
*/
|
||||
public class PeertubeStreamExtractorDefaultTest {
|
||||
private static PeertubeStreamExtractor extractor;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
NewPipe.init(Downloader.getInstance(), new Localization("GB", "en"));
|
||||
extractor = (PeertubeStreamExtractor) PeerTube.getStreamExtractor("https://peertube.mastodon.host/videos/watch/86fe4f24-64c3-4ab4-9e7e-66177219ed21");
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetInvalidTimeStamp() throws ParsingException {
|
||||
assertTrue(extractor.getTimeStamp() + "",
|
||||
extractor.getTimeStamp() <= 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTitle() throws ParsingException {
|
||||
assertEquals(extractor.getName(), "Pažadėtoji 1 Sezonas 1050 Serija - Ziuri.me");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDescription() throws ParsingException {
|
||||
assertEquals(extractor.getDescription(), "Serialo veiksmas vyksta Radžastane. kur vis dar gyvos liaudies tradicijos. o jo centre - Anandi gimusi varguolių šeimoje. Mergaitė privalės ištekėti už turtingo paveldėtojo vos tik sulaukusi aštuonerių metų ir priprasti prie naujojo nuotakos vaidm...");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUploaderName() throws ParsingException {
|
||||
assertEquals(extractor.getUploaderName(), "djsets");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLength() throws ParsingException {
|
||||
assertEquals(extractor.getLength(), 1238);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetViewCount() throws ParsingException {
|
||||
assertTrue(Long.toString(extractor.getViewCount()),
|
||||
extractor.getViewCount() > 700);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUploadDate() throws ParsingException {
|
||||
assertEquals("2018-10-06", extractor.getUploadDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUploaderUrl() throws ParsingException {
|
||||
assertIsSecureUrl(extractor.getUploaderUrl());
|
||||
assertEquals("https://peertube.mastodon.host/api/v1/accounts/djsets@hostyour.tv", extractor.getUploaderUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetThumbnailUrl() throws ParsingException {
|
||||
assertIsSecureUrl(extractor.getThumbnailUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUploaderAvatarUrl() throws ParsingException {
|
||||
assertIsSecureUrl(extractor.getUploaderAvatarUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetVideoStreams() throws IOException, ExtractionException {
|
||||
assertFalse(extractor.getVideoStreams().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStreamType() throws ParsingException {
|
||||
assertTrue(extractor.getStreamType() == StreamType.VIDEO_STREAM);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRelatedVideos() throws ExtractionException, IOException {
|
||||
StreamInfoItemsCollector relatedVideos = extractor.getRelatedVideos();
|
||||
assertFalse(relatedVideos.getItems().isEmpty());
|
||||
assertTrue(relatedVideos.getErrors().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSubtitlesListDefault() throws IOException, ExtractionException {
|
||||
assertTrue(extractor.getSubtitlesDefault().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSubtitlesList() throws IOException, ExtractionException {
|
||||
assertTrue(extractor.getSubtitlesDefault().isEmpty());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.schabi.newpipe.Downloader;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeStreamLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
|
||||
/**
|
||||
* Test for {@link PeertubeStreamLinkHandlerFactory}
|
||||
*/
|
||||
public class PeertubeStreamLinkHandlerFactoryTest {
|
||||
private static PeertubeStreamLinkHandlerFactory linkHandler;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
linkHandler = PeertubeStreamLinkHandlerFactory.getInstance();
|
||||
NewPipe.init(Downloader.getInstance(), new Localization("GB", "en"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getId() throws Exception {
|
||||
assertEquals("986aac60-1263-4f73-9ce5-36b18225cb60", linkHandler.fromUrl("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60").getId());
|
||||
assertEquals("986aac60-1263-4f73-9ce5-36b18225cb60", linkHandler.fromUrl("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60?fsdafs=fsafa").getId());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAcceptUrl() throws ParsingException {
|
||||
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60"));
|
||||
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60?fsdafs=fsafa"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.schabi.newpipe.Downloader;
|
||||
import org.schabi.newpipe.extractor.ListExtractor;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.kiosk.KioskExtractor;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeTrendingExtractor;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
|
||||
/**
|
||||
* Test for {@link PeertubeTrendingExtractor}
|
||||
*/
|
||||
public class PeertubeTrendingExtractorTest {
|
||||
|
||||
static KioskExtractor extractor;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
NewPipe.init(Downloader.getInstance(), new Localization("GB", "en"));
|
||||
extractor = PeerTube
|
||||
.getKioskList()
|
||||
.getExtractorById("Trending", null);
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDownloader() throws Exception {
|
||||
assertNotNull(NewPipe.getDownloader());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetName() throws Exception {
|
||||
assertEquals(extractor.getName(), "Trending");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testId() {
|
||||
assertEquals(extractor.getId(), "Trending");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStreams() throws Exception {
|
||||
ListExtractor.InfoItemsPage<StreamInfoItem> page = extractor.getInitialPage();
|
||||
if(!page.getErrors().isEmpty()) {
|
||||
System.err.println("----------");
|
||||
List<Throwable> errors = page.getErrors();
|
||||
for(Throwable e: errors) {
|
||||
e.printStackTrace();
|
||||
System.err.println("----------");
|
||||
}
|
||||
}
|
||||
assertTrue("no streams are received",
|
||||
!page.getItems().isEmpty()
|
||||
&& page.getErrors().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStreamsErrors() throws Exception {
|
||||
assertTrue("errors during stream list extraction", extractor.getInitialPage().getErrors().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasMoreStreams() throws Exception {
|
||||
// Setup the streams
|
||||
extractor.getInitialPage();
|
||||
assertTrue("has more streams", extractor.hasNextPage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNextPageUrl() throws Exception {
|
||||
assertTrue(extractor.hasNextPage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNextPage() throws Exception {
|
||||
extractor.getInitialPage().getItems();
|
||||
assertFalse("extractor has next streams", extractor.getPage(extractor.getNextPageUrl()) == null
|
||||
|| extractor.getPage(extractor.getNextPageUrl()).getItems().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCleanUrl() throws Exception {
|
||||
assertEquals(extractor.getUrl(), "https://peertube.mastodon.host/api/v1/videos?sort=-views");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.schabi.newpipe.Downloader;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeTrendingLinkHandlerFactory;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
|
||||
/**
|
||||
* Test for {@link PeertubeTrendingLinkHandlerFactory}
|
||||
*/
|
||||
public class PeertubeTrendingLinkHandlerFactoryTest {
|
||||
private static LinkHandlerFactory LinkHandlerFactory;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
LinkHandlerFactory = new PeertubeTrendingLinkHandlerFactory();
|
||||
NewPipe.init(Downloader.getInstance(), new Localization("GB", "en"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUrl()
|
||||
throws Exception {
|
||||
assertEquals(LinkHandlerFactory.fromId("Trending").getUrl(), "https://peertube.mastodon.host/api/v1/videos?sort=-views");
|
||||
assertEquals(LinkHandlerFactory.fromId("Recently added").getUrl(), "https://peertube.mastodon.host/api/v1/videos?sort=-publishedAt");
|
||||
assertEquals(LinkHandlerFactory.fromId("Local").getUrl(), "https://peertube.mastodon.host/api/v1/videos?filter=local");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getId()
|
||||
throws Exception {
|
||||
assertEquals(LinkHandlerFactory.fromUrl("https://peertube.mastodon.host/videos/trending").getId(), "Trending");
|
||||
assertEquals(LinkHandlerFactory.fromUrl("https://peertube.mastodon.host/videos/recently-added").getId(), "Recently added");
|
||||
assertEquals(LinkHandlerFactory.fromUrl("https://peertube.mastodon.host/videos/local").getId(), "Local");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void acceptUrl() throws ParsingException {
|
||||
assertTrue(LinkHandlerFactory.acceptUrl("https://peertube.mastodon.host/videos/trending"));
|
||||
assertTrue(LinkHandlerFactory.acceptUrl("https://peertube.mastodon.host/videos/trending?adsf=fjaj#fhe"));
|
||||
|
||||
assertTrue(LinkHandlerFactory.acceptUrl("https://peertube.mastodon.host/videos/recently-added"));
|
||||
assertTrue(LinkHandlerFactory.acceptUrl("https://peertube.mastodon.host/videos/recently-added?adsf=fjaj#fhe"));
|
||||
|
||||
assertTrue(LinkHandlerFactory.acceptUrl("https://peertube.mastodon.host/videos/local"));
|
||||
assertTrue(LinkHandlerFactory.acceptUrl("https://peertube.mastodon.host/videos/local?adsf=fjaj#fhe"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.search;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.ListExtractor;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeSearchExtractor;
|
||||
|
||||
/**
|
||||
* Test for {@link PeertubeSearchExtractor}
|
||||
*/
|
||||
public abstract class PeertubeSearchExtractorBaseTest {
|
||||
|
||||
protected static PeertubeSearchExtractor extractor;
|
||||
protected static ListExtractor.InfoItemsPage<InfoItem> itemsPage;
|
||||
|
||||
@Test
|
||||
public void testResultListElementsLength() {
|
||||
assertTrue(Integer.toString(itemsPage.getItems().size()),
|
||||
itemsPage.getItems().size() >= 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUrl() throws Exception {
|
||||
assertTrue(extractor.getUrl(), extractor.getUrl().startsWith("https://peertube.mastodon.host/api/v1/search/videos"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.search;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.schabi.newpipe.Downloader;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.ListExtractor;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeSearchExtractor;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.utils.Localization;
|
||||
|
||||
/**
|
||||
* Test for {@link PeertubeSearchExtractor}
|
||||
*/
|
||||
public class PeertubeSearchExtractorDefaultTest extends PeertubeSearchExtractorBaseTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpClass() throws Exception {
|
||||
NewPipe.init(Downloader.getInstance(), new Localization("GB", "en"));
|
||||
extractor = (PeertubeSearchExtractor) PeerTube.getSearchExtractor("internet's own boy");
|
||||
extractor.fetchPage();
|
||||
itemsPage = extractor.getInitialPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSecondPageUrl() throws Exception {
|
||||
assertEquals("", extractor.getNextPageUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResultList_FirstElement() {
|
||||
InfoItem firstInfoItem = itemsPage.getItems().get(0);
|
||||
|
||||
// THe channel should be the first item
|
||||
assertEquals("name", "The Internet's Own Boy", firstInfoItem.getName());
|
||||
assertEquals("url","https://peertube.mastodon.host/api/v1/videos/04af977f-4201-4697-be67-a8d8cae6fa7a", firstInfoItem.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResultListCheckIfContainsStreamItems() {
|
||||
boolean hasStreams = false;
|
||||
for(InfoItem item : itemsPage.getItems()) {
|
||||
if(item instanceof StreamInfoItem) {
|
||||
hasStreams = true;
|
||||
}
|
||||
}
|
||||
assertTrue("Has no InfoItemStreams", hasStreams);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSecondPage() throws Exception {
|
||||
extractor = (PeertubeSearchExtractor) PeerTube.getSearchExtractor("internet");
|
||||
itemsPage = extractor.getInitialPage();
|
||||
PeertubeSearchExtractor secondExtractor =
|
||||
(PeertubeSearchExtractor) PeerTube.getSearchExtractor("internet");
|
||||
ListExtractor.InfoItemsPage<InfoItem> secondPage = secondExtractor.getPage(itemsPage.getNextPageUrl());
|
||||
assertTrue(Integer.toString(secondPage.getItems().size()),
|
||||
secondPage.getItems().size() >= 10);
|
||||
|
||||
// check if its the same result
|
||||
boolean equals = true;
|
||||
for (int i = 0; i < secondPage.getItems().size()
|
||||
&& i < itemsPage.getItems().size(); i++) {
|
||||
if(!secondPage.getItems().get(i).getUrl().equals(
|
||||
itemsPage.getItems().get(i).getUrl())) {
|
||||
equals = false;
|
||||
}
|
||||
}
|
||||
assertFalse("First and second page are equal", equals);
|
||||
|
||||
assertEquals("https://peertube.mastodon.host/api/v1/search/videos?search=internet&start=24&count=12",
|
||||
secondPage.getNextPageUrl());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testId() throws Exception {
|
||||
assertEquals("internet's own boy", extractor.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testName() {
|
||||
assertEquals("internet's own boy", extractor.getName());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package org.schabi.newpipe.extractor.services.peertube.search;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PeertubeSearchQHTest {
|
||||
|
||||
@Test
|
||||
public void testRegularValues() throws Exception {
|
||||
assertEquals("https://peertube.mastodon.host/api/v1/search/videos?search=asdf", PeerTube.getSearchQHFactory().fromQuery("asdf").getUrl());
|
||||
assertEquals("https://peertube.mastodon.host/api/v1/search/videos?search=hans",PeerTube.getSearchQHFactory().fromQuery("hans").getUrl());
|
||||
assertEquals("https://peertube.mastodon.host/api/v1/search/videos?search=Poifj%26jaijf", PeerTube.getSearchQHFactory().fromQuery("Poifj&jaijf").getUrl());
|
||||
assertEquals("https://peertube.mastodon.host/api/v1/search/videos?search=G%C3%BCl%C3%BCm", PeerTube.getSearchQHFactory().fromQuery("Gülüm").getUrl());
|
||||
assertEquals("https://peertube.mastodon.host/api/v1/search/videos?search=%3Fj%24%29H%C2%A7B", PeerTube.getSearchQHFactory().fromQuery("?j$)H§B").getUrl());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue