Merge pull request #758 from litetex/release/v0.21.12

Release 0.21.12
This commit is contained in:
litetex 2021-12-11 16:14:11 +01:00 committed by GitHub
commit 7484b6a098
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 1954 additions and 446 deletions

View File

@ -11,7 +11,7 @@ NewPipe Extractor is available at JitPack's Maven repo.
If you're using Gradle, you could add NewPipe Extractor as a dependency with the following steps:
1. Add `maven { url 'https://jitpack.io' }` to the `repositories` in your `build.gradle`.
2. Add `implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.21.11'`the `dependencies` in your `build.gradle`. Replace `v0.21.11` with the latest release.
2. Add `implementation 'com.github.TeamNewPipe:NewPipeExtractor:INSERT_VERSION_HERE'` to the `dependencies` in your `build.gradle`. Replace `INSERT_VERSION_HERE` with the [latest release](https://github.com/TeamNewPipe/NewPipeExtractor/releases/latest).
**Note:** To use NewPipe Extractor in projects with a `minSdkVersion` below 26, [API desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring) is required.

View File

@ -8,7 +8,7 @@ allprojects {
sourceCompatibility = 1.8
targetCompatibility = 1.8
version 'v0.21.11'
version 'v0.21.12'
group 'com.github.TeamNewPipe'
repositories {
@ -28,7 +28,7 @@ allprojects {
ext {
nanojsonVersion = "1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751"
spotbugsVersion = "4.4.1"
spotbugsVersion = "4.5.0"
junitVersion = "4.13.2"
}
}

View File

@ -16,5 +16,5 @@ dependencies {
testImplementation "junit:junit:$junitVersion"
testImplementation "com.squareup.okhttp3:okhttp:3.12.13"
testImplementation 'com.google.code.gson:gson:2.8.8'
testImplementation 'com.google.code.gson:gson:2.8.9'
}

View File

@ -24,9 +24,9 @@ public class CommentsInfo extends ListInfo<CommentsInfoItem> {
return getInfo(NewPipe.getServiceByUrl(url), url);
}
public static CommentsInfo getInfo(final StreamingService serviceByUrl, final String url)
public static CommentsInfo getInfo(final StreamingService service, final String url)
throws ExtractionException, IOException {
return getInfo(serviceByUrl.getCommentsExtractor(url));
return getInfo(service.getCommentsExtractor(url));
}
public static CommentsInfo getInfo(final CommentsExtractor commentsExtractor)
@ -63,7 +63,7 @@ public class CommentsInfo extends ListInfo<CommentsInfoItem> {
final StreamingService service,
final CommentsInfo commentsInfo,
final Page page) throws IOException, ExtractionException {
if (null == commentsInfo.getCommentsExtractor()) {
if (commentsInfo.getCommentsExtractor() == null) {
commentsInfo.setCommentsExtractor(service.getCommentsExtractor(commentsInfo.getUrl()));
commentsInfo.getCommentsExtractor().fetchPage();
}

View File

@ -10,7 +10,7 @@ import java.util.List;
public class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFactory {
private static final PeertubeChannelLinkHandlerFactory instance = new PeertubeChannelLinkHandlerFactory();
private static final String ID_PATTERN = "(accounts|video-channels)/([^/?&#]*)";
private static final String ID_PATTERN = "((accounts|a)|(video-channels|c))/([^/?&#]*)";
public static final String API_ENDPOINT = "/api/v1/";
public static PeertubeChannelLinkHandlerFactory getInstance() {
@ -19,7 +19,7 @@ public class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFactory {
@Override
public String getId(String url) throws ParsingException {
return Parser.matchGroup(ID_PATTERN, url, 0);
return fixId(Parser.matchGroup(ID_PATTERN, url, 0));
}
@Override
@ -31,7 +31,7 @@ public class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFactory {
public String getUrl(String id, List<String> contentFilter, String sortFilter, String baseUrl)
throws ParsingException {
if (id.matches(ID_PATTERN)) {
return baseUrl + "/" + id;
return baseUrl + "/" + fixId(id);
} else {
// This is needed for compatibility with older versions were we didn't support video channels yet
return baseUrl + "/accounts/" + id;
@ -40,6 +40,28 @@ public class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFactory {
@Override
public boolean onAcceptUrl(String url) {
return url.contains("/accounts/") || url.contains("/video-channels/");
return url.contains("/accounts/") || url.contains("/a/")
|| url.contains("/video-channels/") || url.contains("/c/");
}
/**
* Fix id
*
* <p>
* a/:accountName and c/:channelName ids are supported
* by the PeerTube web client (>= v3.3.0)
* but not by the API.
* </p>
*
* @param id the id to fix
* @return the fixed id
*/
private String fixId(String id) {
if (id.startsWith("a/")) {
id = "accounts" + id.substring(1);
} else if (id.startsWith("c/")) {
id = "video-channels" + id.substring(1);
}
return id;
}
}

View File

@ -11,7 +11,6 @@ import java.util.List;
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() {
@ -20,12 +19,12 @@ public class PeertubeCommentsLinkHandlerFactory extends ListLinkHandlerFactory {
@Override
public String getId(String url) throws ParsingException, IllegalArgumentException {
return Parser.matchGroup(ID_PATTERN, url, 2);
return PeertubeStreamLinkHandlerFactory.getInstance().getId(url); // the same id is needed
}
@Override
public boolean onAcceptUrl(final String url) throws FoundAdException {
return url.contains("/videos/");
return url.contains("/videos/") || url.contains("/w/");
}
@Override

View File

@ -11,7 +11,7 @@ import java.util.List;
public class PeertubePlaylistLinkHandlerFactory extends ListLinkHandlerFactory {
private static final PeertubePlaylistLinkHandlerFactory instance = new PeertubePlaylistLinkHandlerFactory();
private static final String ID_PATTERN = "/videos/watch/playlist/([^/?&#]*)";
private static final String ID_PATTERN = "(/videos/watch/playlist/|/w/p/)([^/?&#]*)";
public static PeertubePlaylistLinkHandlerFactory getInstance() {
return instance;
@ -30,7 +30,7 @@ public class PeertubePlaylistLinkHandlerFactory extends ListLinkHandlerFactory {
@Override
public String getId(String url) throws ParsingException {
return Parser.matchGroup1(ID_PATTERN, url);
return Parser.matchGroup(ID_PATTERN, url, 2);
}
@Override

View File

@ -9,8 +9,13 @@ 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/|embed/)?([^/?&#]*)";
private static final String ID_PATTERN = "(/w/|(/videos/(watch/|embed/)?))(?!p/)([^/?&#]*)";
// we exclude p/ because /w/p/ is playlist, not video
public static final String VIDEO_API_ENDPOINT = "/api/v1/videos/";
// From PeerTube 3.3.0, the default path is /w/.
// We still use /videos/watch/ for compatibility reasons:
// /videos/watch/ is still accepted by >=3.3.0 but /w/ isn't by <3.3.0
private static final String VIDEO_PATH = "/videos/watch/";
private PeertubeStreamLinkHandlerFactory() {
@ -32,7 +37,7 @@ public class PeertubeStreamLinkHandlerFactory extends LinkHandlerFactory {
@Override
public String getId(String url) throws ParsingException, IllegalArgumentException {
return Parser.matchGroup(ID_PATTERN, url, 2);
return Parser.matchGroup(ID_PATTERN, url, 4);
}
@Override

View File

@ -40,8 +40,8 @@ import static org.schabi.newpipe.extractor.ServiceList.SoundCloud;
import static org.schabi.newpipe.extractor.utils.Utils.*;
public class SoundcloudParsingHelper {
private static final String HARDCODED_CLIENT_ID =
"yoxLvaFlJ3V5LbNCt53Cwvw5KXKKxWfn"; // Updated on 01/10/21
static final String HARDCODED_CLIENT_ID =
"1NKODbzHzEpoowFHxTAmS7oB08DObPuK"; // Updated on 08/12/21
private static String clientId;
public static final String SOUNDCLOUD_API_V2_URL = "https://api-v2.soundcloud.com/";

View File

@ -162,6 +162,10 @@ public class YoutubeParsingHelper {
|| host.equalsIgnoreCase("y.com.cm");
}
public static boolean isY2ubeURL(@Nonnull final URL url) {
return url.getHost().equalsIgnoreCase("y2u.be");
}
/**
* Parses the duration string of the video expecting ":" or "." as separators
*

View File

@ -337,19 +337,33 @@ public class YoutubeStreamExtractor extends StreamExtractor {
@Override
public long getLikeCount() throws ParsingException {
assertPageFetched();
String likesString = "";
String likesString = null;
try {
try {
likesString = getVideoPrimaryInfoRenderer().getObject("sentimentBar")
.getObject("sentimentBarRenderer").getString("tooltip").split("/")[0];
} catch (final NullPointerException e) {
likesString = getVideoPrimaryInfoRenderer().getObject("sentimentBar")
.getObject("sentimentBarRenderer").getString("tooltip");
if (likesString != null && likesString.contains("/")) {
likesString = likesString.split("/")[0];
} else {
likesString = getVideoPrimaryInfoRenderer()
.getObject("videoActions")
.getObject("menuRenderer")
.getArray("topLevelButtons")
.getObject(0)
.getObject("toggleButtonRenderer")
.getObject("defaultText")
.getObject("accessibility")
.getObject("accessibilityData")
.getString("label");
}
if (likesString == null) {
// If this kicks in our button has no content and therefore ratings must be disabled
if (playerResponse.getObject("videoDetails").getBoolean("allowRatings")) {
throw new ParsingException(
"Ratings are enabled even though the like button is missing", e);
throw new ParsingException("Ratings are enabled even though the like button is missing");
}
return -1;
}
return Integer.parseInt(Utils.removeNonDigitCharacters(likesString));
} catch (final NumberFormatException nfe) {
throw new ParsingException("Could not parse \"" + likesString + "\" as an Integer",
@ -366,29 +380,28 @@ public class YoutubeStreamExtractor extends StreamExtractor {
public long getDislikeCount() throws ParsingException {
assertPageFetched();
String dislikesString = "";
try {
try {
dislikesString = getVideoPrimaryInfoRenderer().getObject("sentimentBar")
.getObject("sentimentBarRenderer").getString("tooltip").split("/")[1];
} catch (final NullPointerException e) {
// If this kicks in our button has no content and therefore ratings must be disabled
if (playerResponse.getObject("videoDetails").getBoolean("allowRatings")) {
throw new ParsingException(
"Ratings are enabled even though the dislike button is missing", e);
String dislikesString = getVideoPrimaryInfoRenderer().getObject("sentimentBar")
.getObject("sentimentBarRenderer").getString("tooltip");
if (dislikesString != null && dislikesString.contains("/")) {
dislikesString = dislikesString.split("/")[1];
return Integer.parseInt(Utils.removeNonDigitCharacters(dislikesString));
} else {
// Calculate dislike with average rating and like count
long likes = getLikeCount();
double averageRating = playerResponse.getObject("videoDetails").getDouble("averageRating");
if (likes != -1 && averageRating > 1) {
// If averageRating can't be gathered, it will be 0,
// but we also can't divide by 0 so we need > 1
return Math.round(likes * ((5 - averageRating) / (averageRating - 1)));
}
return -1;
}
return Integer.parseInt(Utils.removeNonDigitCharacters(dislikesString));
} catch (final NumberFormatException nfe) {
throw new ParsingException("Could not parse \"" + dislikesString + "\" as an Integer",
nfe);
} catch (final Exception e) {
if (getAgeLimit() == NO_AGE_LIMIT) {
throw new ParsingException("Could not get dislike count", e);
}
return -1;
}
// Silently fail as YouTube is "gradually rolling out" removing dislike count
// https://blog.youtube/news-and-events/update-to-youtube/
return -1;
}
@Nonnull

View File

@ -288,4 +288,19 @@ public class YoutubeStreamInfoItemExtractor implements StreamInfoItemExtractor {
throw new ParsingException("Could not parse date from premiere: \"" + startTime + "\"");
}
}
@Nullable
@Override
public String getShortDescription() throws ParsingException {
if (videoInfo.has("detailedMetadataSnippets")) {
return getTextFromObject(videoInfo.getArray("detailedMetadataSnippets").getObject(0).getObject("snippetText"));
}
if (videoInfo.has("descriptionSnippet")) {
return getTextFromObject(videoInfo.getObject("descriptionSnippet"));
}
return null;
}
}

View File

@ -110,7 +110,7 @@ public class YoutubeStreamLinkHandlerFactory extends LinkHandlerFactory {
if (!Utils.isHTTP(url) || !(YoutubeParsingHelper.isYoutubeURL(url) ||
YoutubeParsingHelper.isYoutubeServiceURL(url) || YoutubeParsingHelper.isHooktubeURL(url) ||
YoutubeParsingHelper.isInvidioURL(url))) {
YoutubeParsingHelper.isInvidioURL(url) || YoutubeParsingHelper.isY2ubeURL(url))) {
if (host.equalsIgnoreCase("googleads.g.doubleclick.net")) {
throw new FoundAdException("Error found ad: " + urlString);
}
@ -160,6 +160,7 @@ public class YoutubeStreamLinkHandlerFactory extends LinkHandlerFactory {
return assertIsId(viewQueryValue);
}
case "Y2U.BE":
case "YOUTU.BE": {
String viewQueryValue = Utils.getQueryValue(url, "v");
if (viewQueryValue != null) {

View File

@ -32,6 +32,7 @@ public class StreamInfoItem extends InfoItem {
private final StreamType streamType;
private String uploaderName;
private String shortDescription;
private String textualUploadDate;
@Nullable
private DateWrapper uploadDate;
@ -92,6 +93,14 @@ public class StreamInfoItem extends InfoItem {
this.uploaderAvatarUrl = uploaderAvatarUrl;
}
public String getShortDescription() {
return shortDescription;
}
public void setShortDescription(final String shortDescription) {
this.shortDescription = shortDescription;
}
@Nullable
public String getTextualUploadDate() {
return textualUploadDate;

View File

@ -116,4 +116,14 @@ public interface StreamInfoItemExtractor extends InfoItemExtractor {
@Nullable
DateWrapper getUploadDate() throws ParsingException;
/**
* Get the video's short description.
*
* @return The video's short description or {@code null} if not provided by the service.
* @throws ParsingException if there is an error in the extraction
*/
@Nullable
default String getShortDescription() throws ParsingException { return null; }
}

View File

@ -101,6 +101,11 @@ public class StreamInfoItemsCollector extends InfoItemsCollector<StreamInfoItem,
} catch (Exception e) {
addError(e);
}
try {
resultItem.setShortDescription(extractor.getShortDescription());
} catch (Exception e) {
addError(e);
}
return resultItem;
}

View File

@ -20,44 +20,55 @@ public class PeertubeChannelLinkHandlerFactoryTest {
@BeforeClass
public static void setUp() {
PeerTube.setInstance(new PeertubeInstance("https://peertube.mastodon.host", "PeerTube on Mastodon.host"));
PeerTube.setInstance(new PeertubeInstance("https://peertube.stream", "PeerTube on peertube.stream"));
linkHandler = PeertubeChannelLinkHandlerFactory.getInstance();
NewPipe.init(DownloaderTestImpl.getInstance());
}
@Test
public void acceptUrlTest() throws ParsingException {
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/accounts/kranti@videos.squat.net"));
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa/videos"));
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/api/v1/accounts/kranti@videos.squat.net/videos"));
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/api/v1/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa"));
assertTrue(linkHandler.acceptUrl("https://peertube.stream/accounts/kranti@videos.squat.net"));
assertTrue(linkHandler.acceptUrl("https://peertube.stream/a/kranti@videos.squat.net"));
assertTrue(linkHandler.acceptUrl("https://peertube.stream/api/v1/accounts/kranti@videos.squat.net/videos"));
assertTrue(linkHandler.acceptUrl("https://peertube.stream/video-channels/kranti_channel@videos.squat.net/videos"));
assertTrue(linkHandler.acceptUrl("https://peertube.stream/c/kranti_channel@videos.squat.net/videos"));
assertTrue(linkHandler.acceptUrl("https://peertube.stream/api/v1/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa"));
}
@Test
public void getId() throws ParsingException {
assertEquals("accounts/kranti@videos.squat.net",
linkHandler.fromUrl("https://peertube.mastodon.host/accounts/kranti@videos.squat.net").getId());
linkHandler.fromUrl("https://peertube.stream/accounts/kranti@videos.squat.net").getId());
assertEquals("accounts/kranti@videos.squat.net",
linkHandler.fromUrl("https://peertube.mastodon.host/accounts/kranti@videos.squat.net/videos").getId());
assertEquals("video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa",
linkHandler.fromUrl("https://peertube.mastodon.host/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa/videos").getId());
linkHandler.fromUrl("https://peertube.stream/a/kranti@videos.squat.net").getId());
assertEquals("accounts/kranti@videos.squat.net",
linkHandler.fromUrl("https://peertube.mastodon.host/api/v1/accounts/kranti@videos.squat.net").getId());
linkHandler.fromUrl("https://peertube.stream/accounts/kranti@videos.squat.net/videos").getId());
assertEquals("accounts/kranti@videos.squat.net",
linkHandler.fromUrl("https://peertube.mastodon.host/api/v1/accounts/kranti@videos.squat.net/videos").getId());
assertEquals("video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa",
linkHandler.fromUrl("https://peertube.mastodon.host/api/v1/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa").getId());
linkHandler.fromUrl("https://peertube.stream/a/kranti@videos.squat.net/videos").getId());
assertEquals("accounts/kranti@videos.squat.net",
linkHandler.fromUrl("https://peertube.stream/api/v1/accounts/kranti@videos.squat.net").getId());
assertEquals("accounts/kranti@videos.squat.net",
linkHandler.fromUrl("https://peertube.stream/api/v1/accounts/kranti@videos.squat.net/videos").getId());
assertEquals("video-channels/kranti_channel@videos.squat.net",
linkHandler.fromUrl("https://peertube.stream/video-channels/kranti_channel@videos.squat.net/videos").getId());
assertEquals("video-channels/kranti_channel@videos.squat.net",
linkHandler.fromUrl("https://peertube.stream/c/kranti_channel@videos.squat.net/videos").getId());
assertEquals("video-channels/kranti_channel@videos.squat.net",
linkHandler.fromUrl("https://peertube.stream/c/kranti_channel@videos.squat.net/video-playlists").getId());
assertEquals("video-channels/kranti_channel@videos.squat.net",
linkHandler.fromUrl("https://peertube.stream/api/v1/video-channels/kranti_channel@videos.squat.net").getId());
}
@Test
public void getUrl() throws ParsingException {
assertEquals("https://peertube.mastodon.host/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa",
linkHandler.fromId("video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa").getUrl());
assertEquals("https://peertube.mastodon.host/accounts/kranti@videos.squat.net",
assertEquals("https://peertube.stream/video-channels/kranti_channel@videos.squat.net",
linkHandler.fromId("video-channels/kranti_channel@videos.squat.net").getUrl());
assertEquals("https://peertube.stream/accounts/kranti@videos.squat.net",
linkHandler.fromId("accounts/kranti@videos.squat.net").getUrl());
assertEquals("https://peertube.mastodon.host/accounts/kranti@videos.squat.net",
assertEquals("https://peertube.stream/accounts/kranti@videos.squat.net",
linkHandler.fromId("kranti@videos.squat.net").getUrl());
assertEquals("https://peertube.mastodon.host/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa",
linkHandler.fromUrl("https://peertube.mastodon.host/api/v1/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa").getUrl());
assertEquals("https://peertube.stream/video-channels/kranti_channel@videos.squat.net",
linkHandler.fromUrl("https://peertube.stream/api/v1/video-channels/kranti_channel@videos.squat.net").getUrl());
}
}

View File

@ -25,12 +25,32 @@ public class PeertubeCommentsLinkHandlerFactoryTest {
@Test
public void acceptUrlTest() throws ParsingException {
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/api/v1/videos/19319/comment-threads?start=0&count=10&sort=-createdAt"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/videos/watch/kkGMgK9ZtnKfYAgnEtQxbv"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/w/kkGMgK9ZtnKfYAgnEtQxbv"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/api/v1/videos/kkGMgK9ZtnKfYAgnEtQxbv/comment-threads?start=0&count=10&sort=-createdAt"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/w/9c9de5e8-0a1e-484a-b099-e80766180a6d"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/api/v1/videos/9c9de5e8-0a1e-484a-b099-e80766180a6d/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());
assertEquals("kkGMgK9ZtnKfYAgnEtQxbv",
linkHandler.fromUrl("https://framatube.org/w/kkGMgK9ZtnKfYAgnEtQxbv").getId());
assertEquals("kkGMgK9ZtnKfYAgnEtQxbv",
linkHandler.fromUrl("https://framatube.org/videos/watch/kkGMgK9ZtnKfYAgnEtQxbv").getId());
assertEquals("kkGMgK9ZtnKfYAgnEtQxbv",
linkHandler.fromUrl("https://framatube.org/api/v1/videos/kkGMgK9ZtnKfYAgnEtQxbv/comment-threads").getId());
assertEquals("kkGMgK9ZtnKfYAgnEtQxbv",
linkHandler.fromUrl("https://framatube.org/api/v1/videos/kkGMgK9ZtnKfYAgnEtQxbv/comment-threads?start=0&count=10&sort=-createdAt").getId());
assertEquals("9c9de5e8-0a1e-484a-b099-e80766180a6d",
linkHandler.fromUrl("https://framatube.org/w/9c9de5e8-0a1e-484a-b099-e80766180a6d").getId());
assertEquals("9c9de5e8-0a1e-484a-b099-e80766180a6d",
linkHandler.fromUrl("https://framatube.org/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d").getId());
assertEquals("9c9de5e8-0a1e-484a-b099-e80766180a6d",
linkHandler.fromUrl("https://framatube.org/api/v1/videos/9c9de5e8-0a1e-484a-b099-e80766180a6d/comment-threads").getId());
assertEquals("9c9de5e8-0a1e-484a-b099-e80766180a6d",
linkHandler.fromUrl("https://framatube.org/api/v1/videos/9c9de5e8-0a1e-484a-b099-e80766180a6d/comment-threads?start=0&count=10&sort=-createdAt").getId());
}
}

View File

@ -26,16 +26,30 @@ public class PeertubePlaylistLinkHandlerFactoryTest {
@Test
public void acceptUrlTest() throws ParsingException {
assertTrue(linkHandler.acceptUrl("https://framatube.org/videos/watch/playlist/d8ca79f9-e4c7-4269-8183-d78ed269c909"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/w/p/d8ca79f9-e4c7-4269-8183-d78ed269c909"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/videos/watch/playlist/d8ca79f9-e4c7-4269-8183-d78ed269c909/videos"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/videos/watch/playlist/dacdc4ef-5160-4846-9b70-a655880da667"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/w/p/dacdc4ef-5160-4846-9b70-a655880da667"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/videos/watch/playlist/96b0ee2b-a5a7-4794-8769-58d8ccb79ab7"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/w/p/96b0ee2b-a5a7-4794-8769-58d8ccb79ab7"));
}
@Test
public void getIdFromUrl() throws ParsingException {
assertEquals("d8ca79f9-e4c7-4269-8183-d78ed269c909", linkHandler.getId("https://framatube.org/videos/watch/playlist/d8ca79f9-e4c7-4269-8183-d78ed269c909"));
assertEquals("d8ca79f9-e4c7-4269-8183-d78ed269c909", linkHandler.getId("https://framatube.org/w/p/d8ca79f9-e4c7-4269-8183-d78ed269c909"));
assertEquals("dacdc4ef-5160-4846-9b70-a655880da667", linkHandler.getId("https://framatube.org/videos/watch/playlist/dacdc4ef-5160-4846-9b70-a655880da667"));
assertEquals("dacdc4ef-5160-4846-9b70-a655880da667", linkHandler.getId("https://framatube.org/w/p/dacdc4ef-5160-4846-9b70-a655880da667"));
assertEquals("bfc145f5-1be7-48a6-9b9e-4f1967199dad", linkHandler.getId("https://framatube.org/videos/watch/playlist/bfc145f5-1be7-48a6-9b9e-4f1967199dad"));
assertEquals("bfc145f5-1be7-48a6-9b9e-4f1967199dad", linkHandler.getId("https://framatube.org/w/p/bfc145f5-1be7-48a6-9b9e-4f1967199dad"));
assertEquals("96b0ee2b-a5a7-4794-8769-58d8ccb79ab7", linkHandler.getId("https://framatube.org/videos/watch/playlist/96b0ee2b-a5a7-4794-8769-58d8ccb79ab7"));
assertEquals("96b0ee2b-a5a7-4794-8769-58d8ccb79ab7", linkHandler.getId("https://framatube.org/w/p/96b0ee2b-a5a7-4794-8769-58d8ccb79ab7"));
}
@Test
public void getUrl() throws ParsingException {
System.out.println(linkHandler.fromUrl("https://framatube.org/videos/watch/playlist/d8ca79f9-e4c7-4269-8183-d78ed269c909").getUrl());;
System.out.println(linkHandler.fromUrl("https://framatube.org/w/p/d8ca79f9-e4c7-4269-8183-d78ed269c909").getUrl());;
System.out.println(linkHandler.fromUrl("https://framatube.org/w/p/sLFbqXsw7sPR3AfvqQSBZB").getUrl());;
}
}

View File

@ -7,19 +7,19 @@ import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeStreamLinkHandlerFactory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import static org.schabi.newpipe.extractor.ServiceList.PeerTube;
/**
* Test for {@link PeertubeStreamLinkHandlerFactory}
*/
public class PeertubeStreamLinkHandlerFactoryTest {
private static PeertubeStreamLinkHandlerFactory linkHandler;
@BeforeClass
public static void setUp() {
PeerTube.setInstance(new PeertubeInstance("https://peertube.mastodon.host", "PeerTube on Mastodon.host"));
PeerTube.setInstance(new PeertubeInstance("https://framatube.org", "Framatube"));
linkHandler = PeertubeStreamLinkHandlerFactory.getInstance();
NewPipe.init(DownloaderTestImpl.getInstance());
}
@ -30,22 +30,31 @@ public class PeertubeStreamLinkHandlerFactoryTest {
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());
assertEquals("9c9de5e8-0a1e-484a-b099-e80766180a6d",
linkHandler.fromUrl("https://framatube.org/videos/embed/9c9de5e8-0a1e-484a-b099-e80766180a6d").getId());
assertEquals("986aac60-1263-4f73-9ce5-36b18225cb60",
linkHandler.fromUrl("https://peertube.mastodon.host/api/v1/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60").getId());
assertEquals("986aac60-1263-4f73-9ce5-36b18225cb60",
linkHandler.fromUrl("https://peertube.mastodon.host/api/v1/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60?fsdafs=fsafa").getId());
assertEquals("9c9de5e8-0a1e-484a-b099-e80766180a6d",
linkHandler.fromUrl("https://framatube.org/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d").getId());
assertEquals("9c9de5e8-0a1e-484a-b099-e80766180a6d",
linkHandler.fromUrl("https://framatube.org/videos/embed/9c9de5e8-0a1e-484a-b099-e80766180a6d").getId());
assertEquals("9c9de5e8-0a1e-484a-b099-e80766180a6d",
linkHandler.fromUrl("https://framatube.org/w/9c9de5e8-0a1e-484a-b099-e80766180a6d").getId());
}
@Test
public void getUrl() throws Exception {
assertEquals("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60",
linkHandler.fromId("986aac60-1263-4f73-9ce5-36b18225cb60").getUrl());
assertEquals("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60",
linkHandler.fromUrl("https://peertube.mastodon.host/api/v1/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60").getUrl());
assertEquals("https://peertube.mastodon.host/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60",
linkHandler.fromUrl("https://peertube.mastodon.host/videos/embed/986aac60-1263-4f73-9ce5-36b18225cb60").getUrl());
assertEquals("https://framatube.org/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d",
linkHandler.fromId("9c9de5e8-0a1e-484a-b099-e80766180a6d").getUrl());
assertEquals("https://framatube.org/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d",
linkHandler.fromUrl("https://framatube.org/api/v1/videos/9c9de5e8-0a1e-484a-b099-e80766180a6d").getUrl());
assertEquals("https://framatube.org/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d",
linkHandler.fromUrl("https://framatube.org/videos/embed/9c9de5e8-0a1e-484a-b099-e80766180a6d").getUrl());
assertEquals("https://framatube.org/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d",
linkHandler.fromUrl("https://framatube.org/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d").getUrl());
assertEquals("https://framatube.org/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d",
linkHandler.fromUrl("https://framatube.org/w/9c9de5e8-0a1e-484a-b099-e80766180a6d").getUrl());
}
@ -53,7 +62,14 @@ public class PeertubeStreamLinkHandlerFactoryTest {
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"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/api/v1/videos/9c9de5e8-0a1e-484a-b099-e80766180a6d"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/videos/embed/9c9de5e8-0a1e-484a-b099-e80766180a6d"));
assertTrue(linkHandler.acceptUrl("https://peertube.mastodon.host/api/v1/videos/watch/986aac60-1263-4f73-9ce5-36b18225cb60?fsdafs=fsafa"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d"));
assertTrue(linkHandler.acceptUrl("https://framatube.org/w/9c9de5e8-0a1e-484a-b099-e80766180a6d"));
// make sure playlists aren't accepted
assertFalse(linkHandler.acceptUrl("https://framatube.org/w/p/dacdc4ef-5160-4846-9b70-a655880da667"));
assertFalse(linkHandler.acceptUrl("https://framatube.org/videos/watch/playlist/dacdc4ef-5160-4846-9b70-a655880da667"));
}
}
}

View File

@ -5,9 +5,13 @@ import org.junit.BeforeClass;
import org.junit.Test;
import org.schabi.newpipe.downloader.DownloaderTestImpl;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
public class SoundcloudParsingHelperTest {
@BeforeClass
public static void setUp() {
@ -20,6 +24,14 @@ public class SoundcloudParsingHelperTest {
SoundcloudParsingHelper.checkIfHardcodedClientIdIsValid());
}
@Test
public void assertHardCodedClientIdMatchesCurrentClientId() throws IOException, ExtractionException {
assertEquals(
"Hardcoded client doesn't match extracted clientId",
SoundcloudParsingHelper.HARDCODED_CLIENT_ID,
SoundcloudParsingHelper.clientId());
}
@Test
public void resolveUrlWithEmbedPlayerTest() throws Exception {
Assert.assertEquals("https://soundcloud.com/trapcity", SoundcloudParsingHelper.resolveUrlWithEmbedPlayer("https://api.soundcloud.com/users/26057743"));

View File

@ -71,7 +71,7 @@ public class SoundcloudStreamExtractorTest {
@Override public boolean expectedHasSubtitles() { return false; }
@Override public boolean expectedHasFrames() { return false; }
@Override public int expectedStreamSegmentsCount() { return 0; }
@Override public boolean expectedHasRelatedItems() { return false; }
@Override public boolean expectedHasRelatedItems() { return true; } // One stream is returned
@Override public String expectedLicence() { return "all-rights-reserved"; }
@Override public String expectedCategory() { return "Pop"; }
}

View File

@ -126,7 +126,7 @@ public class YoutubeChannelExtractorTest {
// "This account has been terminated because we received multiple third-party claims
// of copyright infringement regarding material that the user posted."
final ChannelExtractor extractor =
YouTube.getChannelExtractor("https://www.youtube.com/channel/UCpExuV8qJMfCaSQNL1YG6bQ");
YouTube.getChannelExtractor("https://www.youtube.com/channel/UCI4i4RgFT5ilfMpna4Z_Y8w");
try {
extractor.fetchPage();
} catch (final AccountTerminatedException e) {

View File

@ -308,7 +308,7 @@ public class YoutubeCommentsExtractorTest {
}
public static class RepliesTest {
private final static String url = "https://www.youtube.com/watch?v=--yeOvJGZQk";
private final static String url = "https://www.youtube.com/watch?v=xaQJbozY_Is";
private static YoutubeCommentsExtractor extractor;
@BeforeClass
@ -329,9 +329,11 @@ public class YoutubeCommentsExtractorTest {
CommentsInfoItem firstComment = comments.getItems().get(0);
assertTrue("First comment isn't pinned", firstComment.isPinned());
InfoItemsPage<CommentsInfoItem> replies = extractor.getPage(firstComment.getReplies());
assertEquals("First reply comment did not match", "Lol", replies.getItems().get(0).getCommentText());
assertEquals("First reply comment did not match", "First", replies.getItems().get(0).getCommentText());
}
}
}

View File

@ -61,4 +61,10 @@ public class YoutubeCommentsLinkHandlerFactoryTest {
assertEquals("VM_6n762j6M", linkHandler.fromUrl("https://invidio.us/VM_6n762j6M&t=20").getId());
}
@Test
public void getIdFromY2ube() throws ParsingException {
assertEquals("VM_6n762j6M", linkHandler.fromUrl("https://y2u.be/VM_6n762j6M").getId());
assertEquals("VM_6n762j6M", linkHandler.fromUrl("https://Y2U.Be/VM_6n762j6M").getId());
}
}

View File

@ -343,4 +343,34 @@ public class YoutubeSearchExtractorTest {
}
}
}
public static class VideoDescription extends DefaultSearchExtractorTest {
private static SearchExtractor extractor;
private static final String QUERY = "44wLAzydRFU";
@BeforeClass
public static void setUp() throws Exception {
YoutubeParsingHelper.resetClientVersionAndKey();
YoutubeParsingHelper.setNumberGenerator(new Random(1));
NewPipe.init(new DownloaderFactory().getDownloader(RESOURCE_PATH + "video_description"));
extractor = YouTube.getSearchExtractor(QUERY, singletonList(VIDEOS), "");
extractor.fetchPage();
}
@Override public SearchExtractor extractor() { return extractor; }
@Override public StreamingService expectedService() { return YouTube; }
@Override public String expectedName() { return QUERY; }
@Override public String expectedId() { return QUERY; }
@Override public String expectedUrlContains() { return "youtube.com/results?search_query=" + QUERY; }
@Override public String expectedOriginalUrlContains() { return "youtube.com/results?search_query=" + QUERY; }
@Override public String expectedSearchString() { return QUERY; }
@Nullable @Override public String expectedSearchSuggestion() { return null; }
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.STREAM; }
@Test
public void testVideoDescription() throws IOException, ExtractionException {
final List<InfoItem> items = extractor.getInitialPage().getItems();
assertNotNull(((StreamInfoItem) items.get(0)).getShortDescription());
}
}
}

View File

@ -11,6 +11,7 @@ import org.schabi.newpipe.extractor.stream.StreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamType;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
@ -20,7 +21,7 @@ import static org.schabi.newpipe.extractor.ServiceList.YouTube;
public class YoutubeStreamExtractorAgeRestrictedTest extends DefaultStreamExtractorTest {
private static final String RESOURCE_PATH = DownloaderFactory.RESOURCE_PATH + "services/youtube/extractor/stream/";
private static final String ID = "MmBeUZqv1QA";
private static final String ID = "rwcfPqbAx-0";
private static final int TIMESTAMP = 196;
private static final String URL = YoutubeStreamExtractorDefaultTest.BASE_URL + ID + "&t=" + TIMESTAMP;
private static StreamExtractor extractor;
@ -37,37 +38,34 @@ public class YoutubeStreamExtractorAgeRestrictedTest extends DefaultStreamExtrac
@Override public StreamExtractor extractor() { return extractor; }
@Override public StreamingService expectedService() { return YouTube; }
@Override public String expectedName() { return "FINGERING PORNSTARS @ AVN Expo 2017 In Las Vegas!"; }
@Override public String expectedName() { return "Russian Daft Punk"; }
@Override public String expectedId() { return ID; }
@Override public String expectedUrlContains() { return YoutubeStreamExtractorDefaultTest.BASE_URL + ID; }
@Override public String expectedOriginalUrlContains() { return URL; }
@Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; }
@Override public String expectedUploaderName() { return "EpicFiveTV"; }
@Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCuPUHlLP5POZphOIrjrNxiw"; }
@Override public boolean expectedUploaderVerified() { return true; }
@Override public List<String> expectedDescriptionContains() { return Arrays.asList("http://instagram.com/Ruben_Sole", "AVN"); }
@Override public long expectedLength() { return 1790; }
@Override public String expectedUploaderName() { return "DAN TV"; }
@Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCcQHIVL83g5BEQe2IJFb-6w"; }
@Override public boolean expectedUploaderVerified() { return false; }
@Override public boolean expectedDescriptionIsEmpty() { return true; }
@Override public List<String> expectedDescriptionContains() { return Collections.emptyList(); }
@Override public long expectedLength() { return 10; }
@Override public long expectedTimestamp() { return TIMESTAMP; }
@Override public long expectedViewCountAtLeast() { return 28500000; }
@Nullable @Override public String expectedUploadDate() { return "2017-01-25 00:00:00.000"; }
@Nullable @Override public String expectedTextualUploadDate() { return "2017-01-25"; }
@Override public long expectedLikeCountAtLeast() { return 149000; }
@Override public long expectedDislikeCountAtLeast() { return 38000; }
@Override public long expectedViewCountAtLeast() { return 232_000; }
@Nullable @Override public String expectedUploadDate() { return "2018-03-11 00:00:00.000"; }
@Nullable @Override public String expectedTextualUploadDate() { return "2018-03-11"; }
@Override public long expectedLikeCountAtLeast() { return 3_700; }
@Override public long expectedDislikeCountAtLeast() { return 30; }
@Override public boolean expectedHasRelatedItems() { return false; } // no related videos (!)
@Override public int expectedAgeLimit() { return 18; }
@Override public boolean expectedHasSubtitles() { return false; }
@Override public boolean expectedHasFrames() { return false; }
@Override public String expectedCategory() { return "Entertainment"; }
@Override public String expectedCategory() { return "People & Blogs"; }
@Override public String expectedLicence() { return "YouTube licence"; }
@Override
public List<String> expectedTags() {
return Arrays.asList("AEE", "AEE 2017", "AVN", "AVN 2016", "AVN 2017", "AVN 2017 Expo In Las Vegas",
"AVN Awards Show", "AVN Expo", "AVN Las Vegas", "AVN Magazine", "AVN Vlog", "Ariana Marie",
"August Ames", "Brenna Sparks", "CeCe Capella", "Cindy Starfall", "Elsa Jean", "Emma Hix",
"FINGERING", "FINGERING P0RNSTARS", "FINGERING PORNSTARS", "Kaho Shibuya", "Keisha Grey",
"Kimberly Chi", "Las Vegas", "Mia Martinez", "Pornstar", "Pornstars", "Riley Reid",
"Samantha Saint", "Vegas", "Vicki Chase");
return Collections.emptyList();
}
}

View File

@ -53,7 +53,7 @@ public class YoutubeStreamExtractorLivestreamTest extends DefaultStreamExtractor
@Override public String expectedUploaderName() { return "Lofi Girl"; }
@Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCSJ4gkVC6NrvII8umztf0Ow"; }
@Override public List<String> expectedDescriptionContains() {
return Arrays.asList("https://bit.ly/lofigirI-merch",
return Arrays.asList("Lofi Girl merch",
"Thank you for listening, I hope you will have a good time here");
}
@Override public boolean expectedUploaderVerified() { return true; }

View File

@ -221,7 +221,7 @@
"responseMessage": "",
"responseHeaders": {
"alt-svc": [
"h3\u003d\":443\"; ma\u003d2592000,h3-29\u003d\":443\"; ma\u003d2592000,h3-T051\u003d\":443\"; ma\u003d2592000,h3-Q050\u003d\":443\"; ma\u003d2592000,h3-Q046\u003d\":443\"; ma\u003d2592000,h3-Q043\u003d\":443\"; ma\u003d2592000,quic\u003d\":443\"; ma\u003d2592000; v\u003d\"46,43\""
"h3\u003d\":443\"; ma\u003d2592000,h3-29\u003d\":443\"; ma\u003d2592000,h3-Q050\u003d\":443\"; ma\u003d2592000,h3-Q046\u003d\":443\"; ma\u003d2592000,h3-Q043\u003d\":443\"; ma\u003d2592000,quic\u003d\":443\"; ma\u003d2592000; v\u003d\"46,43\""
],
"cache-control": [
"private"
@ -230,7 +230,7 @@
"application/json; charset\u003dUTF-8"
],
"date": [
"Fri, 30 Jul 2021 17:13:39 GMT"
"Wed, 08 Dec 2021 20:50:38 GMT"
],
"server": [
"ESF"