Skip to content

Commit 670828a

Browse files
authored
Merge pull request #1445 from Stypox/meta-info-fix
[YouTube] Support a new type of meta info
2 parents fc63085 + d6e5743 commit 670828a

11 files changed

Lines changed: 2906 additions & 11 deletions

File tree

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeMetaInfoHelper.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,14 @@ private static MetaInfo getInfoPanelContent(@Nonnull final JsonObject infoPanelC
8585
throw new ParsingException("Could not get metadata info URL", e);
8686
}
8787

88-
final String metaInfoLinkText = getTextFromObject(
89-
infoPanelContentRenderer.getObject("inlineSource"));
88+
final String metaInfoLinkText;
89+
if (infoPanelContentRenderer.has("inlineSource")) {
90+
metaInfoLinkText = getTextFromObject(
91+
infoPanelContentRenderer.getObject("inlineSource"));
92+
} else {
93+
metaInfoLinkText = getTextFromObject(
94+
infoPanelContentRenderer.getObject("disclaimer"));
95+
}
9096
if (isNullOrEmpty(metaInfoLinkText)) {
9197
throw new ParsingException("Could not get metadata info link text.");
9298
}

extractor/src/test/java/org/schabi/newpipe/extractor/ExtractorAsserts.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,16 @@ public static void assertContains(
168168
"'" + shouldBeContained + "' should be contained inside '" + container + "'");
169169
}
170170

171+
public static <T> void assertContains(final T shouldBeContained, final List<T> container) {
172+
assertNotNull(shouldBeContained, "shouldBeContained is null");
173+
assertNotNull(container, "container is null");
174+
final String containerString = container.stream()
175+
.map(Object::toString)
176+
.collect(Collectors.joining(", "));
177+
assertTrue(container.contains(shouldBeContained),
178+
"'" + shouldBeContained + "' should be contained inside [" + containerString + "]");
179+
}
180+
171181
public static void assertTabsContain(@Nonnull final List<ListLinkHandler> tabs,
172182
@Nonnull final String... expectedTabs) {
173183
final Set<String> tabSet = tabs.stream()

extractor/src/test/java/org/schabi/newpipe/extractor/services/DefaultStreamExtractorTest.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.schabi.newpipe.extractor.services;
22

33
import org.junit.jupiter.api.Test;
4+
import org.junit.jupiter.api.function.Executable;
45
import org.schabi.newpipe.extractor.ExtractorAsserts;
56
import org.schabi.newpipe.extractor.InfoItemsCollector;
67
import org.schabi.newpipe.extractor.MediaFormat;
@@ -20,16 +21,19 @@
2021
import java.time.format.DateTimeFormatter;
2122
import java.net.MalformedURLException;
2223
import java.net.URL;
24+
import java.util.ArrayList;
2325
import java.util.Collections;
2426
import java.util.List;
2527
import java.util.Locale;
2628
import java.util.stream.Collectors;
2729

30+
import static org.junit.jupiter.api.Assertions.assertAll;
2831
import static org.junit.jupiter.api.Assertions.assertEquals;
2932
import static org.junit.jupiter.api.Assertions.assertFalse;
3033
import static org.junit.jupiter.api.Assertions.assertNotNull;
3134
import static org.junit.jupiter.api.Assertions.assertNull;
3235
import static org.junit.jupiter.api.Assertions.assertTrue;
36+
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertContains;
3337
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertEmpty;
3438
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertEqualsOrderIndependent;
3539
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertGreaterOrEqual;
@@ -447,6 +451,7 @@ public void testMetaInfo() throws Exception {
447451
final List<MetaInfo> metaInfoList = extractor().getMetaInfo();
448452
final List<MetaInfo> expectedMetaInfoList = expectedMetaInfo();
449453

454+
final List<Executable> assertions = new ArrayList<>();
450455
for (final MetaInfo expectedMetaInfo : expectedMetaInfoList) {
451456
final List<String> texts = metaInfoList.stream()
452457
.map((metaInfo) -> metaInfo.getContent().getContent())
@@ -457,16 +462,17 @@ public void testMetaInfo() throws Exception {
457462
final List<String> urlTexts = metaInfoList.stream().flatMap(info -> info.getUrlTexts().stream())
458463
.collect(Collectors.toList());
459464

460-
assertTrue(texts.contains(expectedMetaInfo.getContent().getContent()));
461-
assertTrue(titles.contains(expectedMetaInfo.getTitle()));
465+
assertions.add(() -> assertContains(expectedMetaInfo.getContent().getContent(), texts));
466+
assertions.add(() -> assertContains(expectedMetaInfo.getTitle(), titles));
462467

463468
for (final String expectedUrlText : expectedMetaInfo.getUrlTexts()) {
464-
assertTrue(urlTexts.contains(expectedUrlText));
469+
assertions.add(() -> assertContains(expectedUrlText, urlTexts));
465470
}
466471
for (final URL expectedUrl : expectedMetaInfo.getUrls()) {
467-
assertTrue(urls.contains(expectedUrl));
472+
assertions.add(() -> assertContains(expectedUrl, urls));
468473
}
469474
}
475+
assertAll(assertions);
470476
}
471477

472478
@Test

extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorDefaultTest.java

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ public void testTags() {}
368368
}
369369

370370
public static class PublicBroadcasterTest extends DefaultStreamExtractorTest
371-
implements InitYoutubeTest {
371+
implements InitYoutubeTest {
372372
private static final String ID = "cJ9to6EmElQ";
373373
private static final int TIMESTAMP = 0;
374374
private static final String URL = BASE_URL + ID;
@@ -400,10 +400,8 @@ protected StreamExtractor createExtractor() throws Exception {
400400
@Override public List<MetaInfo> expectedMetaInfo() throws MalformedURLException {
401401
return Collections.singletonList(new MetaInfo(
402402
"",
403-
new Description("Arte is a French/German public broadcast service.",
404-
Description.PLAIN_TEXT),
405-
List.of(new URL(
406-
"https://en.wikipedia.org/wiki/Arte?wprov=yicw1")),
403+
new Description("Arte is a French/German public broadcast service.", Description.PLAIN_TEXT),
404+
List.of(new URL("https://en.wikipedia.org/wiki/Arte?wprov=yicw1")),
407405
List.of("Wikipedia")
408406
));
409407
}
@@ -417,6 +415,59 @@ protected StreamExtractor createExtractor() throws Exception {
417415
// @formatter:on
418416
}
419417

418+
public static class LicensedDoctorTest extends DefaultStreamExtractorTest
419+
implements InitYoutubeTest {
420+
private static final String ID = "rCAS2eD-mcw";
421+
private static final int TIMESTAMP = 0;
422+
private static final String URL = BASE_URL + ID;
423+
424+
@Override
425+
protected StreamExtractor createExtractor() throws Exception {
426+
return YouTube.getStreamExtractor(URL);
427+
}
428+
429+
// @formatter:off
430+
@Override public StreamingService expectedService() { return YouTube; }
431+
@Override public String expectedName() { return "Laryngeal Mask Airway (LMA) insertion | ESSENTIAL TECHNIQUES for standard patients"; }
432+
@Override public String expectedId() { return ID; }
433+
@Override public String expectedUrlContains() { return BASE_URL + ID; }
434+
@Override public String expectedOriginalUrlContains() { return URL; }
435+
436+
@Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; }
437+
@Override public String expectedUploaderName() { return "ABCs of Anaesthesia"; }
438+
@Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCs1fy2n5Ey0c9VZRBL7UCsg"; }
439+
@Override public long expectedUploaderSubscriberCountAtLeast() { return 200_000; }
440+
@Override public List<String> expectedDescriptionContains() { return Arrays.asList("https://www.facebook.com/groups/2082807131964430", "LMA"); }
441+
@Override public long expectedLength() { return 343; }
442+
@Override public long expectedTimestamp() { return TIMESTAMP; }
443+
@Override public long expectedViewCountAtLeast() { return 60_000; }
444+
@Nullable @Override public String expectedUploadDate() { return "2022-07-03 11:00:25.000"; }
445+
@Nullable @Override public String expectedTextualUploadDate() { return "2022-07-03T04:00:25-07:00"; }
446+
@Override public long expectedLikeCountAtLeast() { return 800; }
447+
@Override public long expectedDislikeCountAtLeast() { return -1; }
448+
@Override public List<MetaInfo> expectedMetaInfo() throws MalformedURLException {
449+
return Collections.singletonList(new MetaInfo(
450+
"",
451+
new Description("From a licensed doctor in Australia", Description.PLAIN_TEXT),
452+
List.of(new URL("https://support.google.com/youtube/answer/9795167")),
453+
List.of("Learn more about how experts define health sources")
454+
));
455+
}
456+
@Override public boolean expectedUploaderVerified() { return true; }
457+
@Override public String expectedLicence() { return YOUTUBE_LICENCE; }
458+
@Override public String expectedCategory() { return "Education"; }
459+
@Override public List<String> expectedTags() {
460+
return Arrays.asList("ANZCA", "Anaesthesia", "FANZCA", "LMA", "Vortex", "abcs of anaesthesia",
461+
"airway", "anaesthesiology", "anaesthetics", "anaesthetist", "anesthesia", "anesthesiologist",
462+
"anesthesiology", "anesthetics", "anesthetist", "bag", "basics", "cannula insertion technique",
463+
"cannulation procedure", "cannulation tips and tricks", "cico", "classic", "cuff", "das",
464+
"difficult airway", "igel", "intravenous cannula insertion", "intubation", "laryngeal", "mask",
465+
"medical", "medicine", "nurse", "oxygenation", "procedure", "proseal", "student", "supreme",
466+
"technique", "tips", "venepuncture", "ventilation");
467+
}
468+
// @formatter:on
469+
}
470+
420471
public static class NoVisualMetadataVideoTest extends DefaultStreamExtractorTest
421472
implements InitYoutubeTest {
422473
// Video without visual metadata on YouTube clients (video title, upload date, channel name,

0 commit comments

Comments
 (0)