diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/search/SearchExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/search/SearchExtractor.java index 0101b96f0..4290d6948 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/search/SearchExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/search/SearchExtractor.java @@ -25,6 +25,16 @@ public abstract class SearchExtractor extends ListExtractor { return getLinkHandler().getSearchString(); } + /** + * The search suggestion provided by the service. + *

+ * This method may also return the corrected query, + * see {@link SearchExtractor#isCorrectedSearch()}. + * + * @return a suggestion to another query, the corrected query, or an empty String. + * @throws ParsingException + */ + @Nonnull public abstract String getSearchSuggestion() throws ParsingException; @Override diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCSearchExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCSearchExtractor.java index 67f19a838..c4b368923 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCSearchExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCSearchExtractor.java @@ -11,6 +11,7 @@ import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor; import org.schabi.newpipe.extractor.downloader.Downloader; import org.schabi.newpipe.extractor.exceptions.ExtractionException; +import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandler; import org.schabi.newpipe.extractor.search.InfoItemsSearchCollector; import org.schabi.newpipe.extractor.search.SearchExtractor; @@ -42,9 +43,10 @@ public class MediaCCCSearchExtractor extends SearchExtractor { } } + @Nonnull @Override - public String getSearchSuggestion() { - return null; + public String getSearchSuggestion() throws ParsingException { + return ""; } @Override diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeSearchExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeSearchExtractor.java index 958f53619..352164de3 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeSearchExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeSearchExtractor.java @@ -19,6 +19,7 @@ import org.schabi.newpipe.extractor.utils.JsonUtils; import org.schabi.newpipe.extractor.utils.Parser; import org.schabi.newpipe.extractor.utils.Parser.RegexException; +import javax.annotation.Nonnull; import java.io.IOException; public class PeertubeSearchExtractor extends SearchExtractor { @@ -35,9 +36,10 @@ public class PeertubeSearchExtractor extends SearchExtractor { super(service, linkHandler); } + @Nonnull @Override public String getSearchSuggestion() throws ParsingException { - return null; + return ""; } @Override diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudSearchExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudSearchExtractor.java index b121d56c3..24f5987ec 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudSearchExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudSearchExtractor.java @@ -33,9 +33,10 @@ public class SoundcloudSearchExtractor extends SearchExtractor { super(service, linkHandler); } + @Nonnull @Override public String getSearchSuggestion() { - return null; + return ""; } @Override diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMusicSearchExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMusicSearchExtractor.java index a6ea6531f..95b8c9f85 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMusicSearchExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMusicSearchExtractor.java @@ -18,6 +18,7 @@ import org.schabi.newpipe.extractor.localization.TimeAgoParser; import org.schabi.newpipe.extractor.search.InfoItemsSearchCollector; import org.schabi.newpipe.extractor.search.SearchExtractor; import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper; +import org.schabi.newpipe.extractor.utils.JsonUtils; import org.schabi.newpipe.extractor.utils.Utils; import java.io.IOException; @@ -124,15 +125,27 @@ public class YoutubeMusicSearchExtractor extends SearchExtractor { return super.getUrl(); } + @Nonnull @Override public String getSearchSuggestion() throws ParsingException { - final JsonObject didYouMeanRenderer = initialData.getObject("contents").getObject("sectionListRenderer") - .getArray("contents").getObject(0).getObject("itemSectionRenderer") - .getArray("contents").getObject(0).getObject("didYouMeanRenderer"); - if (!didYouMeanRenderer.has("correctedQuery")) { + final JsonObject itemSectionRenderer = initialData.getObject("contents").getObject("sectionListRenderer") + .getArray("contents").getObject(0).getObject("itemSectionRenderer"); + if (itemSectionRenderer == null) { + return ""; + } + + final JsonObject didYouMeanRenderer = itemSectionRenderer.getArray("contents") + .getObject(0).getObject("didYouMeanRenderer"); + final JsonObject showingResultsForRenderer = itemSectionRenderer.getArray("contents").getObject(0) + .getObject("showingResultsForRenderer"); + + if (didYouMeanRenderer != null) { + return getTextFromObject(didYouMeanRenderer.getObject("correctedQuery")); + } else if (showingResultsForRenderer != null) { + return JsonUtils.getString(showingResultsForRenderer, "correctedQueryEndpoint.searchEndpoint.query"); + } else { return ""; } - return getTextFromObject(didYouMeanRenderer.getObject("correctedQuery")); } @Override diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSearchExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSearchExtractor.java index 69e27e2f5..8c18c6024 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSearchExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeSearchExtractor.java @@ -61,17 +61,25 @@ public class YoutubeSearchExtractor extends SearchExtractor { return super.getUrl() + "&gl=" + getExtractorContentCountry().getCountryCode(); } + @Nonnull @Override public String getSearchSuggestion() throws ParsingException { - final JsonObject didYouMeanRenderer = initialData.getObject("contents") + final JsonObject itemSectionRenderer = initialData.getObject("contents") .getObject("twoColumnSearchResultsRenderer").getObject("primaryContents") .getObject("sectionListRenderer").getArray("contents").getObject(0) - .getObject("itemSectionRenderer").getArray("contents").getObject(0) + .getObject("itemSectionRenderer"); + final JsonObject didYouMeanRenderer = itemSectionRenderer.getArray("contents").getObject(0) .getObject("didYouMeanRenderer"); - if (didYouMeanRenderer == null) { + final JsonObject showingResultsForRenderer = itemSectionRenderer.getArray("contents").getObject(0) + .getObject("showingResultsForRenderer"); + + if (didYouMeanRenderer != null) { + return JsonUtils.getString(didYouMeanRenderer, "correctedQueryEndpoint.searchEndpoint.query"); + } else if (showingResultsForRenderer != null) { + return getTextFromObject(showingResultsForRenderer.getObject("correctedQuery")); + } else { return ""; } - return JsonUtils.getString(didYouMeanRenderer, "correctedQueryEndpoint.searchEndpoint.query"); } @Override diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/search/YoutubeMusicSearchExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/search/YoutubeMusicSearchExtractorTest.java index 2dc4c2814..eeac8c49b 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/search/YoutubeMusicSearchExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/search/YoutubeMusicSearchExtractorTest.java @@ -154,6 +154,7 @@ public class YoutubeMusicSearchExtractorTest { public static class CorrectedSearch extends DefaultSearchExtractorTest { private static SearchExtractor extractor; private static final String QUERY = "duo lipa"; + private static final String EXPECTED_SUGGESTION = "dua lipa"; @BeforeClass public static void setUp() throws Exception { @@ -169,7 +170,7 @@ public class YoutubeMusicSearchExtractorTest { @Override public String expectedUrlContains() { return "music.youtube.com/search?q=" + URLEncoder.encode(QUERY); } @Override public String expectedOriginalUrlContains() { return "music.youtube.com/search?q=" + URLEncoder.encode(QUERY); } @Override public String expectedSearchString() { return QUERY; } - @Nullable @Override public String expectedSearchSuggestion() { return null; } + @Nullable @Override public String expectedSearchSuggestion() { return EXPECTED_SUGGESTION; } @Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.STREAM; } @Override public boolean isCorrectedSearch() { return true; } } diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/search/YoutubeSearchExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/search/YoutubeSearchExtractorTest.java index 9cc4ad1ff..4f7d46d52 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/search/YoutubeSearchExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/search/YoutubeSearchExtractorTest.java @@ -7,6 +7,7 @@ import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.StreamingService; +import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.search.SearchExtractor; import org.schabi.newpipe.extractor.services.DefaultSearchExtractorTest; @@ -138,6 +139,7 @@ public class YoutubeSearchExtractorTest { public static class CorrectedSearch extends DefaultSearchExtractorTest { private static SearchExtractor extractor; private static final String QUERY = "pewdeipie"; + private static final String EXPECTED_SUGGESTION = "pewdiepie"; @BeforeClass public static void setUp() throws Exception { @@ -153,7 +155,7 @@ public class YoutubeSearchExtractorTest { @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; } + @Nullable @Override public String expectedSearchSuggestion() { return EXPECTED_SUGGESTION; } @Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.STREAM; } @Override public boolean isCorrectedSearch() { return true; } }