Merge branch 'dev' into yt-webm-opus
This commit is contained in:
commit
fbb9a86c9f
|
@ -82,6 +82,11 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getId() throws ParsingException {
|
public String getId() throws ParsingException {
|
||||||
|
try {
|
||||||
|
return doc.select("meta[itemprop=\"channelId\"]").first().attr("content");
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
|
||||||
|
// fallback method; does not work with channels that have no "Subscribe" button (e.g. EminemVEVO)
|
||||||
try {
|
try {
|
||||||
Element element = doc.getElementsByClass("yt-uix-subscription-button").first();
|
Element element = doc.getElementsByClass("yt-uix-subscription-button").first();
|
||||||
if (element == null) element = doc.getElementsByClass("yt-uix-subscription-preferences-button").first();
|
if (element == null) element = doc.getElementsByClass("yt-uix-subscription-preferences-button").first();
|
||||||
|
@ -135,11 +140,12 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getSubscriberCount() throws ParsingException {
|
public long getSubscriberCount() throws ParsingException {
|
||||||
final String el = doc.select("span[class*=\"yt-subscription-button-subscriber-count\"]")
|
|
||||||
.first().attr("title");
|
final Element el = doc.select("span[class*=\"yt-subscription-button-subscriber-count\"]").first();
|
||||||
if (el != null) {
|
if (el != null) {
|
||||||
|
String elTitle = el.attr("title");
|
||||||
try {
|
try {
|
||||||
return Utils.mixedNumberWordToLong(el);
|
return Utils.mixedNumberWordToLong(elTitle);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw new ParsingException("Could not get subscriber count", e);
|
throw new ParsingException("Could not get subscriber count", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ public class YoutubeChannelInfoItemExtractor implements ChannelInfoItemExtractor
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUrl() throws ParsingException {
|
public String getUrl() throws ParsingException {
|
||||||
|
try {
|
||||||
String buttonTrackingUrl = el.select("button[class*=\"yt-uix-button\"]").first()
|
String buttonTrackingUrl = el.select("button[class*=\"yt-uix-button\"]").first()
|
||||||
.attr("abs:data-href");
|
.attr("abs:data-href");
|
||||||
|
|
||||||
|
@ -64,11 +65,16 @@ public class YoutubeChannelInfoItemExtractor implements ChannelInfoItemExtractor
|
||||||
|
|
||||||
if (match.matches()) {
|
if (match.matches()) {
|
||||||
return YoutubeChannelExtractor.CHANNEL_URL_BASE + match.group(1);
|
return YoutubeChannelExtractor.CHANNEL_URL_BASE + match.group(1);
|
||||||
} else {
|
}
|
||||||
// fallback method just in case youtube changes things; it should never run and tests will fail
|
} catch(Exception ignored) {}
|
||||||
// provides an url with "/user/NAME", that is inconsistent with stream and channel extractor
|
|
||||||
|
// fallback method for channels without "Subscribe" button (or just in case yt changes things)
|
||||||
|
// provides an url with "/user/NAME", inconsistent with stream and channel extractor: tests will fail
|
||||||
|
try {
|
||||||
return el.select("a[class*=\"yt-uix-tile-link\"]").first()
|
return el.select("a[class*=\"yt-uix-tile-link\"]").first()
|
||||||
.attr("abs:href");
|
.attr("abs:href");
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new ParsingException("Could not get channel url", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -575,9 +575,13 @@ public class YoutubeStreamExtractor extends StreamExtractor {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getErrorMessage() {
|
public String getErrorMessage() {
|
||||||
String errorMessage = doc.select("h1[id=\"unavailable-message\"]").first().text();
|
|
||||||
StringBuilder errorReason;
|
StringBuilder errorReason;
|
||||||
|
Element errorElement = doc.select("h1[id=\"unavailable-message\"]").first();
|
||||||
|
|
||||||
|
if (errorElement == null) {
|
||||||
|
errorReason = null;
|
||||||
|
} else {
|
||||||
|
String errorMessage = errorElement.text();
|
||||||
if (errorMessage == null || errorMessage.isEmpty()) {
|
if (errorMessage == null || errorMessage.isEmpty()) {
|
||||||
errorReason = null;
|
errorReason = null;
|
||||||
} else if (errorMessage.contains("GEMA")) {
|
} else if (errorMessage.contains("GEMA")) {
|
||||||
|
@ -591,6 +595,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
|
||||||
errorReason.append(" ");
|
errorReason.append(" ");
|
||||||
errorReason.append(doc.select("[id=\"unavailable-submessage\"]").first().text());
|
errorReason.append(doc.select("[id=\"unavailable-submessage\"]").first().text());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return errorReason != null ? errorReason.toString() : null;
|
return errorReason != null ? errorReason.toString() : null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -392,6 +392,100 @@ public class YoutubeChannelExtractorTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this channel has no "Subscribe" button
|
||||||
|
public static class EminemVEVO implements BaseChannelExtractorTest {
|
||||||
|
private static YoutubeChannelExtractor extractor;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUp() throws Exception {
|
||||||
|
NewPipe.init(Downloader.getInstance(), new Localization("GB", "en"));
|
||||||
|
extractor = (YoutubeChannelExtractor) YouTube
|
||||||
|
.getChannelExtractor("https://www.youtube.com/user/EminemVEVO/");
|
||||||
|
extractor.fetchPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
|
// Extractor
|
||||||
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testServiceId() {
|
||||||
|
assertEquals(YouTube.getServiceId(), extractor.getServiceId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testName() throws Exception {
|
||||||
|
assertEquals("EminemVEVO", extractor.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testId() throws Exception {
|
||||||
|
assertEquals("UC20vb-R_px4CguHzzBPhoyQ", extractor.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUrl() throws ParsingException {
|
||||||
|
assertEquals("https://www.youtube.com/channel/UC20vb-R_px4CguHzzBPhoyQ", extractor.getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOriginalUrl() throws ParsingException {
|
||||||
|
assertEquals("https://www.youtube.com/user/EminemVEVO/", extractor.getOriginalUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
|
// ListExtractor
|
||||||
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRelatedItems() throws Exception {
|
||||||
|
defaultTestRelatedItems(extractor, YouTube.getServiceId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMoreRelatedItems() throws Exception {
|
||||||
|
defaultTestMoreItems(extractor, YouTube.getServiceId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
|
// ChannelExtractor
|
||||||
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDescription() throws Exception {
|
||||||
|
final String description = extractor.getDescription();
|
||||||
|
assertTrue(description, description.contains("Eminem on Vevo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAvatarUrl() throws Exception {
|
||||||
|
String avatarUrl = extractor.getAvatarUrl();
|
||||||
|
assertIsSecureUrl(avatarUrl);
|
||||||
|
assertTrue(avatarUrl, avatarUrl.contains("yt3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBannerUrl() throws Exception {
|
||||||
|
String bannerUrl = extractor.getBannerUrl();
|
||||||
|
assertIsSecureUrl(bannerUrl);
|
||||||
|
assertTrue(bannerUrl, bannerUrl.contains("yt3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFeedUrl() throws Exception {
|
||||||
|
assertEquals("https://www.youtube.com/feeds/videos.xml?channel_id=UC20vb-R_px4CguHzzBPhoyQ", extractor.getFeedUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSubscriberCount() throws Exception {
|
||||||
|
// there is no "Subscribe" button
|
||||||
|
long subscribers = extractor.getSubscriberCount();
|
||||||
|
assertEquals("Wrong subscriber count", -1, subscribers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class RandomChannel implements BaseChannelExtractorTest {
|
public static class RandomChannel implements BaseChannelExtractorTest {
|
||||||
private static YoutubeChannelExtractor extractor;
|
private static YoutubeChannelExtractor extractor;
|
||||||
|
|
||||||
|
@ -483,8 +577,9 @@ public class YoutubeChannelExtractorTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSubscriberCount() throws Exception {
|
public void testSubscriberCount() throws Exception {
|
||||||
assertTrue("Wrong subscriber count", extractor.getSubscriberCount() >= 50);
|
long subscribers = extractor.getSubscriberCount();
|
||||||
|
assertTrue("Wrong subscriber count: " + subscribers, subscribers >= 50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue