Skip to content

Commit 2fb9922

Browse files
committed
[SoundCloud] Detect whether there are any more search results
Add test for this edge case.
1 parent 5492343 commit 2fb9922

2 files changed

Lines changed: 60 additions & 12 deletions

File tree

extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudSearchExtractor.java

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
import javax.annotation.Nonnull;
3434

3535
public class SoundcloudSearchExtractor extends SearchExtractor {
36-
private JsonArray initialSearchCollection;
36+
private JsonObject initialSearchObject;
37+
private static final String COLLECTION = "collection";
38+
private static final String TOTAL_RESULTS = "total_results";
3739

3840
public SoundcloudSearchExtractor(final StreamingService service,
3941
final SearchQueryHandler linkHandler) {
@@ -60,9 +62,15 @@ public List<MetaInfo> getMetaInfo() {
6062
@Nonnull
6163
@Override
6264
public InfoItemsPage<InfoItem> getInitialPage() throws IOException, ExtractionException {
63-
return new InfoItemsPage<>(
64-
collectItems(initialSearchCollection),
65-
getNextPageFromCurrentUrl(getUrl(), currentOffset -> ITEMS_PER_PAGE));
65+
if (initialSearchObject.getInt(TOTAL_RESULTS) > ITEMS_PER_PAGE) {
66+
return new InfoItemsPage<>(
67+
collectItems(initialSearchObject.getArray(COLLECTION)),
68+
getNextPageFromCurrentUrl(getUrl(), currentOffset -> ITEMS_PER_PAGE));
69+
} else {
70+
return new InfoItemsPage<>(
71+
collectItems(initialSearchObject.getArray(COLLECTION)), null);
72+
}
73+
6674
}
6775

6876
@Override
@@ -74,17 +82,29 @@ public InfoItemsPage<InfoItem> getPage(final Page page) throws IOException,
7482

7583
final Downloader dl = getDownloader();
7684
final JsonArray searchCollection;
85+
final int totalResults;
7786
try {
7887
final String response = dl.get(page.getUrl(), getExtractorLocalization())
7988
.responseBody();
80-
searchCollection = JsonParser.object().from(response).getArray("collection");
89+
final JsonObject result = JsonParser.object().from(response);
90+
searchCollection = result.getArray(COLLECTION);
91+
totalResults = result.getInt(TOTAL_RESULTS);
8192
} catch (final JsonParserException e) {
8293
throw new ParsingException("Could not parse json response", e);
8394
}
95+
final boolean hasNextPage;
96+
try {
97+
hasNextPage = getOffsetFromUrl(page.getUrl()) + ITEMS_PER_PAGE <= totalResults;
98+
} catch (MalformedURLException | UnsupportedEncodingException e) {
99+
throw new ParsingException("Could not get offset from page URL", e);
100+
}
101+
if (hasNextPage) {
102+
return new InfoItemsPage<>(collectItems(searchCollection),
103+
getNextPageFromCurrentUrl(page.getUrl(),
104+
currentOffset -> currentOffset + ITEMS_PER_PAGE));
105+
}
106+
return new InfoItemsPage<>(collectItems(searchCollection), null);
84107

85-
return new InfoItemsPage<>(collectItems(searchCollection),
86-
getNextPageFromCurrentUrl(page.getUrl(),
87-
currentOffset -> currentOffset + ITEMS_PER_PAGE));
88108
}
89109

90110
@Override
@@ -94,12 +114,12 @@ public void onFetchPage(@Nonnull final Downloader downloader) throws IOException
94114
final String url = getUrl();
95115
try {
96116
final String response = dl.get(url, getExtractorLocalization()).responseBody();
97-
initialSearchCollection = JsonParser.object().from(response).getArray("collection");
117+
initialSearchObject = JsonParser.object().from(response);
98118
} catch (final JsonParserException e) {
99119
throw new ParsingException("Could not parse json response", e);
100120
}
101121

102-
if (initialSearchCollection.isEmpty()) {
122+
if (initialSearchObject.getArray(COLLECTION).isEmpty()) {
103123
throw new SearchExtractor.NothingFoundException("Nothing found");
104124
}
105125
}
@@ -134,12 +154,16 @@ private InfoItemsCollector<InfoItem, InfoItemExtractor> collectItems(
134154
private Page getNextPageFromCurrentUrl(final String currentUrl,
135155
final IntUnaryOperator newPageOffsetCalculator)
136156
throws MalformedURLException, UnsupportedEncodingException {
137-
final int currentPageOffset = Integer.parseInt(
138-
Parser.compatParseMap(new URL(currentUrl).getQuery()).get("offset"));
157+
final int currentPageOffset = getOffsetFromUrl(currentUrl);
139158

140159
return new Page(
141160
currentUrl.replace(
142161
"&offset=" + currentPageOffset,
143162
"&offset=" + newPageOffsetCalculator.applyAsInt(currentPageOffset)));
144163
}
164+
165+
private int getOffsetFromUrl(final String url)
166+
throws MalformedURLException, UnsupportedEncodingException {
167+
return Integer.parseInt(Parser.compatParseMap(new URL(url).getQuery()).get("offset"));
168+
}
145169
}

extractor/src/test/java/org/schabi/newpipe/extractor/services/soundcloud/search/SoundcloudSearchExtractorTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.schabi.newpipe.extractor.services.soundcloud.search;
22

3+
import static org.junit.jupiter.api.Assertions.assertFalse;
34
import static org.junit.jupiter.api.Assertions.assertTrue;
45
import static org.schabi.newpipe.extractor.ServiceList.SoundCloud;
56
import static org.schabi.newpipe.extractor.services.DefaultTests.assertNoDuplicatedItems;
@@ -181,4 +182,27 @@ void testIsVerified() throws IOException, ExtractionException {
181182
assertTrue(verified);
182183
}
183184
}
185+
186+
public static class NoNextPage extends DefaultSearchExtractorTest {
187+
188+
private static SearchExtractor extractor;
189+
private static final String QUERY = "Dan at hor#berlgbd";
190+
191+
@BeforeAll
192+
public static void setUp() throws Exception {
193+
NewPipe.init(DownloaderTestImpl.getInstance());
194+
extractor = SoundCloud.getSearchExtractor(QUERY);
195+
extractor.fetchPage();
196+
}
197+
198+
@Override public boolean expectedHasMoreItems() { return false; }
199+
@Override public SearchExtractor extractor() throws Exception { return extractor; }
200+
@Override public StreamingService expectedService() throws Exception { return SoundCloud; }
201+
@Override public String expectedName() throws Exception { return QUERY; }
202+
@Override public String expectedId() throws Exception { return QUERY; }
203+
@Override public String expectedUrlContains() { return "soundcloud.com/search?q=" + urlEncode(QUERY); }
204+
@Override public String expectedOriginalUrlContains() { return "soundcloud.com/search?q=" + urlEncode(QUERY); }
205+
@Override public String expectedSearchString() { return QUERY; }
206+
@Nullable @Override public String expectedSearchSuggestion() { return null; }
207+
}
184208
}

0 commit comments

Comments
 (0)