Skip to content

Commit

Permalink
Invidious support
Browse files Browse the repository at this point in the history
  • Loading branch information
B0pol committed Feb 21, 2021
1 parent a9aa385 commit a76c618
Show file tree
Hide file tree
Showing 42 changed files with 2,671 additions and 162 deletions.
27 changes: 27 additions & 0 deletions extractor/src/main/java/org/schabi/newpipe/extractor/Instance.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.schabi.newpipe.extractor;

import org.schabi.newpipe.extractor.exceptions.InvalidInstanceException;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public interface Instance {

@Nullable
String getName();

@Nonnull
String getUrl();

boolean isValid();

/**
* Fetch instance metadata.
* <p>
* You can e.g. save the name
*
* @throws InvalidInstanceException
*/
void fetchInstanceMetaData() throws InvalidInstanceException;

}
10 changes: 10 additions & 0 deletions extractor/src/main/java/org/schabi/newpipe/extractor/NewPipe.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class NewPipe {
private static Downloader downloader;
private static Localization preferredLocalization;
private static ContentCountry preferredContentCountry;
private static boolean useInvidiousForYouTube;

private NewPipe() {
}
Expand Down Expand Up @@ -154,4 +155,13 @@ public static ContentCountry getPreferredContentCountry() {
public static void setPreferredContentCountry(ContentCountry preferredContentCountry) {
NewPipe.preferredContentCountry = preferredContentCountry;
}

public static boolean getUseInvidiousForYoutube() {
return useInvidiousForYouTube;
}

public static void setUseInvidiousForYoutube(final boolean useInvidiousForYoutube) {
NewPipe.useInvidiousForYouTube = useInvidiousForYoutube;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.schabi.newpipe.extractor.services.peertube.PeertubeService;
import org.schabi.newpipe.extractor.services.soundcloud.SoundcloudService;
import org.schabi.newpipe.extractor.services.youtube.YoutubeService;
import org.schabi.newpipe.extractor.services.youtube.invidious.InvidiousService;

import java.util.Arrays;
import java.util.Collections;
Expand Down Expand Up @@ -39,6 +40,7 @@ private ServiceList() {
public static final SoundcloudService SoundCloud;
public static final MediaCCCService MediaCCC;
public static final PeertubeService PeerTube;
public static final InvidiousService Invidious;

/**
* When creating a new service, put this service in the end of this list,
Expand All @@ -52,12 +54,20 @@ private ServiceList() {
PeerTube = new PeertubeService(3)
));

private static final List<StreamingService> SERVICES_WITH_INVIDIOUS = Collections.unmodifiableList(
Arrays.asList(
Invidious = new InvidiousService(0),
SoundCloud,
MediaCCC,
PeerTube
));

/**
* Get all the supported services.
*
* @return a unmodifiable list of all the supported services
*/
public static List<StreamingService> all() {
return SERVICES;
return NewPipe.getUseInvidiousForYoutube() ? SERVICES_WITH_INVIDIOUS : SERVICES;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ public static class ServiceInfo {

/**
* Creates a new instance of a ServiceInfo
* @param name the name of the service
*
* @param name the name of the service
* @param mediaCapabilities the type of media this service can handle
*/
public ServiceInfo(String name, List<MediaCapability> mediaCapabilities) {
Expand All @@ -69,7 +70,7 @@ public List<MediaCapability> getMediaCapabilities() {
}

public enum MediaCapability {
AUDIO, VIDEO, LIVE, COMMENTS
AUDIO, VIDEO, LIVE, COMMENTS, INSTANCES
}
}

Expand All @@ -86,15 +87,16 @@ public enum LinkType {

private final int serviceId;
private final ServiceInfo serviceInfo;
private Instance instance;

/**
* Creates a new Streaming service.
* If you Implement one do not set id within your implementation of this extractor, instead
* set the id when you put the extractor into
* <a href="https://teamnewpipe.github.io/NewPipeExtractor/javadoc/org/schabi/newpipe/extractor/ServiceList.html">ServiceList</a>.
* set the id when you put the extractor into {@link ServiceList}.
* All other parameters can be set directly from the overriding constructor.
* @param id the number of the service to identify him within the NewPipe frontend
* @param name the name of the service
*
* @param id the number of the service to identify him within the NewPipe frontend
* @param name the name of the service
* @param capabilities the type of media this service can handle
*/
public StreamingService(int id, String name, List<ServiceInfo.MediaCapability> capabilities) {
Expand Down Expand Up @@ -123,29 +125,34 @@ public String toString() {

/**
* Must return a new instance of an implementation of LinkHandlerFactory for streams.
*
* @return an instance of a LinkHandlerFactory for streams
*/
public abstract LinkHandlerFactory getStreamLHFactory();

/**
* Must return a new instance of an implementation of ListLinkHandlerFactory for channels.
* If support for channels is not given null must be returned.
*
* @return an instance of a ListLinkHandlerFactory for channels or null
*/
public abstract ListLinkHandlerFactory getChannelLHFactory();

/**
* Must return a new instance of an implementation of ListLinkHandlerFactory for playlists.
* If support for playlists is not given null must be returned.
*
* @return an instance of a ListLinkHandlerFactory for playlists or null
*/
public abstract ListLinkHandlerFactory getPlaylistLHFactory();

/**
* Must return an instance of an implementation of SearchQueryHandlerFactory.
*
* @return an instance of a SearchQueryHandlerFactory
*/
public abstract SearchQueryHandlerFactory getSearchQHFactory();

public abstract ListLinkHandlerFactory getCommentsLHFactory();

/*//////////////////////////////////////////////////////////////////////////
Expand All @@ -154,19 +161,22 @@ public String toString() {

/**
* Must create a new instance of a SearchExtractor implementation.
*
* @param queryHandler specifies the keyword lock for, and the filters which should be applied.
* @return a new SearchExtractor instance
*/
public abstract SearchExtractor getSearchExtractor(SearchQueryHandler queryHandler);

/**
* Must create a new instance of a SuggestionExtractor implementation.
*
* @return a new SuggestionExtractor instance
*/
public abstract SuggestionExtractor getSuggestionExtractor();

/**
* Outdated or obsolete. null can be returned.
*
* @return just null
*/
public abstract SubscriptionExtractor getSubscriptionExtractor();
Expand All @@ -186,13 +196,15 @@ public FeedExtractor getFeedExtractor(String url) throws ExtractionException {

/**
* Must create a new instance of a KioskList implementation.
*
* @return a new KioskList instance
* @throws ExtractionException
*/
public abstract KioskList getKioskList() throws ExtractionException;

/**
* Must create a new instance of a ChannelExtractor implementation.
*
* @param linkHandler is pointing to the channel which should be handled by this new instance.
* @return a new ChannelExtractor
* @throws ExtractionException
Expand All @@ -201,6 +213,7 @@ public FeedExtractor getFeedExtractor(String url) throws ExtractionException {

/**
* Must crete a new instance of a PlaylistExtractor implementation.
*
* @param linkHandler is pointing to the playlist which should be handled by this new instance.
* @return a new PlaylistExtractor
* @throws ExtractionException
Expand All @@ -209,6 +222,7 @@ public FeedExtractor getFeedExtractor(String url) throws ExtractionException {

/**
* Must create a new instance of a StreamExtractor implementation.
*
* @param linkHandler is pointing to the stream which should be handled by this new instance.
* @return a new StreamExtractor
* @throws ExtractionException
Expand Down Expand Up @@ -276,6 +290,7 @@ public CommentsExtractor getCommentsExtractor(String url) throws ExtractionExcep

/**
* Figures out where the link is pointing to (a channel, a video, a playlist, etc.)
*
* @param url the url on which it should be decided of which link type it is
* @return the link type of url
*/
Expand Down Expand Up @@ -387,4 +402,12 @@ public TimeAgoParser getTimeAgoParser(Localization localization) {
throw new IllegalArgumentException("Localization is not supported (\"" + localization.toString() + "\")");
}

public Instance getInstance() {
return this.instance;
}

public void setInstance(final Instance instance) {
this.instance = instance;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.schabi.newpipe.extractor.exceptions;

public class InvalidInstanceException extends ExtractionException {
public InvalidInstanceException(String message) {
super(message);
}

public InvalidInstanceException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public String getUrl(String id, String baseUrl) throws ParsingException {
}

/**
* Will returns content filter the corresponding extractor can handle like "channels", "videos", "music", etc.
* Will return content filter the corresponding extractor can handle like "channels", "videos", "music", etc.
*
* @return filter that can be applied when building a query for getting a list
*/
Expand All @@ -95,7 +95,7 @@ public String[] getAvailableContentFilter() {
}

/**
* Will returns sort filter the corresponding extractor can handle like "A-Z", "oldest first", "size", etc.
* Will return sort filter the corresponding extractor can handle like "A-Z", "oldest first", "size", etc.
*
* @return filter that can be applied when building a query for getting a list
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,28 @@
import com.grack.nanojson.JsonObject;
import com.grack.nanojson.JsonParser;
import com.grack.nanojson.JsonParserException;

import org.schabi.newpipe.extractor.Instance;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.extractor.downloader.Response;
import org.schabi.newpipe.extractor.exceptions.InvalidInstanceException;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipe.extractor.utils.JsonUtils;
import org.schabi.newpipe.extractor.utils.Utils;

import java.io.IOException;

public class PeertubeInstance {
public class PeertubeInstance implements Instance {

private final String url;
private String name;
private Boolean isValid = null;

public static final PeertubeInstance defaultInstance = new PeertubeInstance("https://framatube.org", "FramaTube");

public PeertubeInstance(String url) {
this.url = url;
this.name = "PeerTube";
this(url, "PeerTube");
}

public PeertubeInstance(String url, String name) {
Expand All @@ -34,25 +36,39 @@ public String getUrl() {
return url;
}

public void fetchInstanceMetaData() throws Exception {
@Override
public boolean isValid() {
if (isValid != null) {
return isValid;
}

try {
fetchInstanceMetaData();
return isValid = true;
} catch (InvalidInstanceException e) {
return isValid = false;
}
}

public void fetchInstanceMetaData() throws InvalidInstanceException {
Downloader downloader = NewPipe.getDownloader();
Response response = null;
Response response;

try {
response = downloader.get(url + "/api/v1/config");
} catch (ReCaptchaException | IOException e) {
throw new Exception("unable to configure instance " + url, e);
throw new InvalidInstanceException("unable to configure instance " + url, e);
}

if (response == null || Utils.isBlank(response.responseBody())) {
throw new Exception("unable to configure instance " + url);
throw new InvalidInstanceException("unable to configure instance " + url);
}

try {
JsonObject json = JsonParser.object().from(response.responseBody());
this.name = JsonUtils.getString(json, "instance.name");
} catch (JsonParserException | ParsingException e) {
throw new Exception("unable to parse instance config", e);
throw new InvalidInstanceException("unable to parse instance config", e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
import java.util.List;

import static java.util.Arrays.asList;
import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.COMMENTS;
import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.VIDEO;
import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.*;

/**
* PeertubeService, uses documented API: https://docs.joinpeertube.org/api-rest-reference.html
*/
public class PeertubeService extends StreamingService {

private PeertubeInstance instance;
Expand All @@ -29,9 +31,9 @@ public PeertubeService(int id) {
this(id, PeertubeInstance.defaultInstance);
}

public PeertubeService(int id, PeertubeInstance instance) {
super(id, "PeerTube", asList(VIDEO, COMMENTS));
this.instance = instance;
public PeertubeService(int id, final PeertubeInstance instance) {
super(id, "PeerTube", asList(VIDEO, COMMENTS, INSTANCES));
setInstance(instance);
}

@Override
Expand Down Expand Up @@ -110,15 +112,7 @@ public CommentsExtractor getCommentsExtractor(ListLinkHandler linkHandler)

@Override
public String getBaseUrl() {
return instance.getUrl();
}

public PeertubeInstance getInstance() {
return this.instance;
}

public void setInstance(PeertubeInstance instance) {
this.instance = instance;
return getInstance().getUrl();
}

@Override
Expand Down
Loading

0 comments on commit a76c618

Please sign in to comment.