Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Invidious support #555

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;

}
Copy link
Member

@FireMasterK FireMasterK Feb 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add the missing newline.

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