add soundcloud SearchExtractor
This commit is contained in:
parent
5718d5b8b4
commit
ef2ce6854c
4 changed files with 127 additions and 11 deletions
|
@ -0,0 +1,113 @@
|
||||||
|
package org.schabi.newpipe.extractor.services.soundcloud;
|
||||||
|
|
||||||
|
import com.grack.nanojson.JsonArray;
|
||||||
|
import com.grack.nanojson.JsonObject;
|
||||||
|
import com.grack.nanojson.JsonParser;
|
||||||
|
import com.grack.nanojson.JsonParserException;
|
||||||
|
import org.schabi.newpipe.extractor.*;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
|
import org.schabi.newpipe.extractor.search.InfoItemsSearchCollector;
|
||||||
|
import org.schabi.newpipe.extractor.search.SearchEngine;
|
||||||
|
import org.schabi.newpipe.extractor.search.SearchExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.search.SearchQueryUrlHandler;
|
||||||
|
import org.schabi.newpipe.extractor.utils.Parser;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import static org.schabi.newpipe.extractor.services.soundcloud.SoundcloudSearchQueryUrlHandler.ITEMS_PER_PAGE;
|
||||||
|
|
||||||
|
public class SoundcloudSearchExtractor extends SearchExtractor {
|
||||||
|
|
||||||
|
private JsonArray searchCollection;
|
||||||
|
|
||||||
|
public SoundcloudSearchExtractor(StreamingService service,
|
||||||
|
SearchQueryUrlHandler urlIdHandler,
|
||||||
|
String contentCountry) {
|
||||||
|
super(service, urlIdHandler, contentCountry);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSearchSuggestion() throws ParsingException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public InfoItemsPage<InfoItem> getInitialPage() throws IOException, ExtractionException {
|
||||||
|
return new InfoItemsPage<>(collectItems(searchCollection), getNextPageUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNextPageUrl() throws IOException, ExtractionException {
|
||||||
|
return getNextPageUrlFromCurrentUrl(getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InfoItemsPage<InfoItem> getPage(String pageUrl) throws IOException, ExtractionException {
|
||||||
|
final Downloader dl = getDownloader();
|
||||||
|
try {
|
||||||
|
searchCollection = JsonParser.object().from(dl.download(pageUrl)).getArray("collection");
|
||||||
|
} catch (JsonParserException e) {
|
||||||
|
throw new ParsingException("Could not parse json response", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new InfoItemsPage<>(collectItems(searchCollection), getNextPageUrlFromCurrentUrl(pageUrl));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFetchPage(@Nonnull Downloader downloader) throws IOException, ExtractionException {
|
||||||
|
final Downloader dl = getDownloader();
|
||||||
|
final String url = getUrl();
|
||||||
|
try {
|
||||||
|
searchCollection = JsonParser.object().from(dl.download(url)).getArray("collection");
|
||||||
|
} catch (JsonParserException e) {
|
||||||
|
throw new ParsingException("Could not parse json response", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchCollection.size() == 0) {
|
||||||
|
throw new SearchEngine.NothingFoundException("Nothing found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private InfoItemsCollector<InfoItem, InfoItemExtractor> collectItems(JsonArray searchCollection) {
|
||||||
|
final InfoItemsSearchCollector collector = getInfoItemSearchCollector();
|
||||||
|
|
||||||
|
for (Object result : searchCollection) {
|
||||||
|
if (!(result instanceof JsonObject)) continue;
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
JsonObject searchResult = (JsonObject) result;
|
||||||
|
String kind = searchResult.getString("kind", "");
|
||||||
|
switch (kind) {
|
||||||
|
case "user":
|
||||||
|
collector.commit(new SoundcloudChannelInfoItemExtractor(searchResult));
|
||||||
|
break;
|
||||||
|
case "track":
|
||||||
|
collector.commit(new SoundcloudStreamInfoItemExtractor(searchResult));
|
||||||
|
break;
|
||||||
|
case "playlist":
|
||||||
|
collector.commit(new SoundcloudPlaylistInfoItemExtractor(searchResult));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return collector;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getNextPageUrlFromCurrentUrl(String currentUrl)
|
||||||
|
throws MalformedURLException, UnsupportedEncodingException {
|
||||||
|
final int pageOffset = Integer.parseInt(
|
||||||
|
Parser.compatParseMap(
|
||||||
|
new URL(currentUrl)
|
||||||
|
.getQuery())
|
||||||
|
.get("offset"));
|
||||||
|
|
||||||
|
return currentUrl.replace("&offset=" +
|
||||||
|
Integer.toString(pageOffset),
|
||||||
|
"&offset=" + Integer.toString(pageOffset + ITEMS_PER_PAGE));
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
|
||||||
public class SoundcloudQueryUrlHandler extends SearchQueryUrlHandler {
|
public class SoundcloudSearchQueryUrlHandler extends SearchQueryUrlHandler {
|
||||||
public static final String CHARSET_UTF_8 = "UTF-8";
|
public static final String CHARSET_UTF_8 = "UTF-8";
|
||||||
|
|
||||||
public static final String TRACKS = "tracks";
|
public static final String TRACKS = "tracks";
|
||||||
|
@ -16,6 +16,8 @@ public class SoundcloudQueryUrlHandler extends SearchQueryUrlHandler {
|
||||||
public static final String PLAYLIST = "playlist";
|
public static final String PLAYLIST = "playlist";
|
||||||
public static final String ANY = "any";
|
public static final String ANY = "any";
|
||||||
|
|
||||||
|
public static final int ITEMS_PER_PAGE = 10;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUrl() throws ParsingException {
|
public String getUrl() throws ParsingException {
|
||||||
try {
|
try {
|
||||||
|
@ -40,7 +42,8 @@ public class SoundcloudQueryUrlHandler extends SearchQueryUrlHandler {
|
||||||
|
|
||||||
return url + "?q=" + URLEncoder.encode(id, CHARSET_UTF_8)
|
return url + "?q=" + URLEncoder.encode(id, CHARSET_UTF_8)
|
||||||
+ "&client_id=" + SoundcloudParsingHelper.clientId()
|
+ "&client_id=" + SoundcloudParsingHelper.clientId()
|
||||||
+ "&limit=10";
|
+ "&limit=" + ITEMS_PER_PAGE
|
||||||
|
+ "&offset=0";
|
||||||
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
throw new ParsingException("Could not encode query", e);
|
throw new ParsingException("Could not encode query", e);
|
|
@ -31,12 +31,12 @@ public class SoundcloudService extends StreamingService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SearchExtractor getSearchExtractor(SearchQueryUrlHandler queryHandler, String contentCountry) {
|
public SearchExtractor getSearchExtractor(SearchQueryUrlHandler queryHandler, String contentCountry) {
|
||||||
return null;
|
return new SoundcloudSearchExtractor(this, queryHandler, contentCountry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SearchQueryUrlHandler getSearchQueryHandler() {
|
public SearchQueryUrlHandler getSearchQueryHandler() {
|
||||||
return null;
|
return new SoundcloudSearchQueryUrlHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -56,17 +56,17 @@ public class SoundcloudService extends StreamingService {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StreamExtractor getStreamExtractor(UrlIdHandler urlIdHandler) throws ExtractionException {
|
public StreamExtractor getStreamExtractor(UrlIdHandler urlIdHandler) {
|
||||||
return new SoundcloudStreamExtractor(this, urlIdHandler);
|
return new SoundcloudStreamExtractor(this, urlIdHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelExtractor getChannelExtractor(ListUrlIdHandler urlIdHandler) throws ExtractionException {
|
public ChannelExtractor getChannelExtractor(ListUrlIdHandler urlIdHandler) {
|
||||||
return new SoundcloudChannelExtractor(this, urlIdHandler);
|
return new SoundcloudChannelExtractor(this, urlIdHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlaylistExtractor getPlaylistExtractor(ListUrlIdHandler urlIdHandler) throws ExtractionException {
|
public PlaylistExtractor getPlaylistExtractor(ListUrlIdHandler urlIdHandler) {
|
||||||
return new SoundcloudPlaylistExtractor(this, urlIdHandler);
|
return new SoundcloudPlaylistExtractor(this, urlIdHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,14 +80,14 @@ public class YoutubeSearchExtractor extends SearchExtractor {
|
||||||
|
|
||||||
private String getNextPageUrlFromCurrentUrl(String currentUrl)
|
private String getNextPageUrlFromCurrentUrl(String currentUrl)
|
||||||
throws MalformedURLException, UnsupportedEncodingException {
|
throws MalformedURLException, UnsupportedEncodingException {
|
||||||
int nextPageNr = Integer.parseInt(
|
final int pageNr = Integer.parseInt(
|
||||||
Parser.compatParseMap(
|
Parser.compatParseMap(
|
||||||
new URL(currentUrl)
|
new URL(currentUrl)
|
||||||
.getQuery())
|
.getQuery())
|
||||||
.get("page")) + 1;
|
.get("page"));
|
||||||
|
|
||||||
return currentUrl.replace("&page=" + Integer.toString( nextPageNr-1),
|
return currentUrl.replace("&page=" + Integer.toString( pageNr),
|
||||||
"&page=" + Integer.toString(nextPageNr));
|
"&page=" + Integer.toString(pageNr + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private InfoItemsSearchCollector collectItems(Document doc) throws NothingFoundException {
|
private InfoItemsSearchCollector collectItems(Document doc) throws NothingFoundException {
|
||||||
|
|
Loading…
Reference in a new issue