From 822cf307f723613baaaa2fde0bbb78aaa1d4082a Mon Sep 17 00:00:00 2001 From: Xiang Rong Lin <41164160+XiangRongLin@users.noreply.github.com> Date: Tue, 17 Mar 2020 14:04:46 +0100 Subject: [PATCH] [Youtube] Add _ITEMS constants and improve code style Move thumbnail id exctraction code to getThumbnailUrlFromId Add test for "My mix" detection to service tests Use ITEM_COUNT_UNKNOWN everywhere instead of -1 and add some tests --- .../MediaCCCConferenceInfoItemExtractor.java | 4 +- .../YoutubeChannelInfoItemExtractor.java | 3 +- .../YoutubeMixPlaylistExtractor.java | 63 +++++++++---------- .../YoutubeMixPlaylistExtractorTest.java | 15 +++++ .../services/youtube/YoutubeServiceTest.java | 8 ++- 5 files changed, 55 insertions(+), 38 deletions(-) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/infoItems/MediaCCCConferenceInfoItemExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/infoItems/MediaCCCConferenceInfoItemExtractor.java index 9099cb1a7..cea663edb 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/infoItems/MediaCCCConferenceInfoItemExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/infoItems/MediaCCCConferenceInfoItemExtractor.java @@ -1,6 +1,8 @@ package org.schabi.newpipe.extractor.services.media_ccc.extractors.infoItems; import com.grack.nanojson.JsonObject; + +import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor; import org.schabi.newpipe.extractor.exceptions.ParsingException; @@ -23,7 +25,7 @@ public class MediaCCCConferenceInfoItemExtractor implements ChannelInfoItemExtra @Override public long getStreamCount() { - return -1; + return ListExtractor.ITEM_COUNT_UNKNOWN; } @Override diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeChannelInfoItemExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeChannelInfoItemExtractor.java index 881fbd794..fbab74d83 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeChannelInfoItemExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeChannelInfoItemExtractor.java @@ -2,6 +2,7 @@ package org.schabi.newpipe.extractor.services.youtube.extractors; import com.grack.nanojson.JsonObject; +import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory; @@ -86,7 +87,7 @@ public class YoutubeChannelInfoItemExtractor implements ChannelInfoItemExtractor try { if (!channelInfoItem.has("videoCountText")) { // Video count is not available, channel probably has no public uploads. - return -1; + return ListExtractor.ITEM_COUNT_UNKNOWN; } return Long.parseLong(Utils.removeNonDigitCharacters(getTextFromObject( diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistExtractor.java index f4868a61e..060edc20b 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistExtractor.java @@ -7,6 +7,8 @@ import com.grack.nanojson.JsonObject; import java.io.IOException; import javax.annotation.Nonnull; import javax.annotation.Nullable; + +import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.downloader.Downloader; import org.schabi.newpipe.extractor.exceptions.ExtractionException; @@ -23,6 +25,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; */ public class YoutubeMixPlaylistExtractor extends PlaylistExtractor { + private final static String CONTENTS = "contents"; private final static String RESPONSE = "response"; private final static String PLAYLIST = "playlist"; @@ -41,44 +44,25 @@ public class YoutubeMixPlaylistExtractor extends PlaylistExtractor { final String url = getUrl() + "&pbj=1"; final JsonArray ajaxJson = getJsonResponse(url, getExtractorLocalization()); JsonObject initialData = ajaxJson.getObject(3).getObject(RESPONSE); - try { - playlistData = initialData.getObject(CONTENTS).getObject(TWO_COLUMNS_WATCH_NEXT_RESULTS) - .getObject(PLAYLIST).getObject(PLAYLIST); - } catch (NullPointerException e) { - throw new ExtractionException(e); - } - + playlistData = initialData.getObject(CONTENTS).getObject(TWO_COLUMN_WATCH_NEXT_RESULTS) + .getObject(PLAYLIST).getObject(PLAYLIST); } @Nonnull @Override public String getName() throws ParsingException { - try { - final String name = playlistData.getString("title"); - if (name != null) { - return name; - } else { - return ""; - } - } catch (Exception e) { - throw new ParsingException("Could not get playlist name", e); + final String name = playlistData.getString("title"); + if (name == null) { + throw new ParsingException("Could not get playlist name"); } + return name; } @Override public String getThumbnailUrl() throws ParsingException { try { final String playlistId = playlistData.getString("playlistId"); - final String videoId; - if (playlistId.startsWith("RDMM")) { - videoId = playlistId.substring(4); - } else { - videoId = playlistId.substring(2); - } - if (videoId.isEmpty()) { - throw new ParsingException(""); - } - return getThumbnailUrlFromId(videoId); + return getThumbnailUrlFromId(playlistId); } catch (Exception e) { throw new ParsingException("Could not get playlist thumbnail", e); } @@ -97,20 +81,20 @@ public class YoutubeMixPlaylistExtractor extends PlaylistExtractor { @Override public String getUploaderName() { - //Youtube mix are auto-generated - return ""; + //Youtube mix are auto-generated by YouTube + return "YouTube"; } @Override public String getUploaderAvatarUrl() { - //Youtube mix are auto-generated + //Youtube mix are auto-generated by YouTube return ""; } @Override public long getStreamCount() { // Auto-generated playlist always start with 25 videos and are endless - return 25; + return ListExtractor.ITEM_COUNT_INFINITE; } @Nonnull @@ -135,7 +119,7 @@ public class YoutubeMixPlaylistExtractor extends PlaylistExtractor { @Override public InfoItemsPage getPage(final String pageUrl) - throws ExtractionException, IOException { + throws ExtractionException, IOException { if (pageUrl == null || pageUrl.isEmpty()) { throw new ExtractionException( new IllegalArgumentException("Page url is empty or null")); @@ -145,7 +129,7 @@ public class YoutubeMixPlaylistExtractor extends PlaylistExtractor { final JsonArray ajaxJson = getJsonResponse(pageUrl, getExtractorLocalization()); playlistData = ajaxJson.getObject(3).getObject(RESPONSE).getObject(CONTENTS) - .getObject(TWO_COLUMNS_WATCH_NEXT_RESULTS).getObject(PLAYLIST) + .getObject(TWO_COLUMN_WATCH_NEXT_RESULTS).getObject(PLAYLIST) .getObject(PLAYLIST); final JsonArray streams = playlistData.getArray(CONTENTS); //Because continuation requests are created with the last video of previous request as start @@ -155,8 +139,8 @@ public class YoutubeMixPlaylistExtractor extends PlaylistExtractor { } private void collectStreamsFrom( - @Nonnull StreamInfoItemsCollector collector, - @Nullable JsonArray streams) { + @Nonnull StreamInfoItemsCollector collector, + @Nullable JsonArray streams) { collector.reset(); if (streams == null) { @@ -176,7 +160,16 @@ public class YoutubeMixPlaylistExtractor extends PlaylistExtractor { } } - private String getThumbnailUrlFromId(String videoId) { + private String getThumbnailUrlFromId(String playlistId) throws ParsingException { + final String videoId; + if (playlistId.startsWith("RDMM")) { + videoId = playlistId.substring(4); + } else { + videoId = playlistId.substring(2); + } + if (videoId.isEmpty()) { + throw new ParsingException("videoId is empty"); + } return "https://i.ytimg.com/vi/" + videoId + "/hqdefault.jpg"; } } diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeMixPlaylistExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeMixPlaylistExtractorTest.java index 0d21ad8c6..d18e4fc55 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeMixPlaylistExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeMixPlaylistExtractorTest.java @@ -93,6 +93,11 @@ public class YoutubeMixPlaylistExtractorTest { public void getStreamCount() throws Exception { assertEquals(ListExtractor.ITEM_COUNT_INFINITE, extractor.getStreamCount()); } + + @Test + public void getStreamCount() throws Exception { + assertEquals(ListExtractor.ITEM_COUNT_INFINITE, extractor.getStreamCount()); + } } public static class MixWithIndex { @@ -165,6 +170,11 @@ public class YoutubeMixPlaylistExtractorTest { public void getStreamCount() { assertEquals(ListExtractor.ITEM_COUNT_INFINITE, extractor.getStreamCount()); } + + @Test + public void getStreamCount() throws Exception { + assertEquals(ListExtractor.ITEM_COUNT_INFINITE, extractor.getStreamCount()); + } } public static class MyMix { @@ -319,5 +329,10 @@ public class YoutubeMixPlaylistExtractorTest { public void getStreamCount() throws Exception { assertEquals(ListExtractor.ITEM_COUNT_INFINITE, extractor.getStreamCount()); } + + @Test + public void getStreamCount() throws Exception { + assertEquals(ListExtractor.ITEM_COUNT_INFINITE, extractor.getStreamCount()); + } } } \ No newline at end of file diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeServiceTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeServiceTest.java index de4fe53fc..7b5d2ce73 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeServiceTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeServiceTest.java @@ -75,7 +75,13 @@ public class YoutubeServiceTest { assertTrue(extractor instanceof YoutubeMixPlaylistExtractor); extractor = YouTube.getPlaylistExtractor( - "https://www.youtube.com/watch?v=" + videoId + "&list=RD" + videoId); + "https://www.youtube.com/watch?v=" + videoId + "&list=RDMM" + videoId); + assertTrue(extractor instanceof YoutubeMixPlaylistExtractor); + + final String mixVideoId = "qHtzO49SDmk"; + + extractor = YouTube.getPlaylistExtractor( + "https://www.youtube.com/watch?v=" + mixVideoId + "&list=RD" + videoId); assertTrue(extractor instanceof YoutubeMixPlaylistExtractor); } }