mirror of
https://github.com/TeamNewPipe/NewPipeExtractor.git
synced 2025-04-29 00:10:35 +05:30
[SoundCloud] Add tabs support for users
Support of tracks, playlists and albums has been added for users. Also add the declaration of the UnsupportedOperationException exception to the service's LinkHandlers. Co-authored-by: ThetaDev <t.testboy@gmail.com> Co-authored-by: Stypox <stypox@pm.me>
This commit is contained in:
parent
6f7d1f079f
commit
d4bfe791ee
@ -8,6 +8,7 @@ import org.jsoup.Jsoup;
|
|||||||
import org.jsoup.nodes.Document;
|
import org.jsoup.nodes.Document;
|
||||||
import org.jsoup.nodes.Element;
|
import org.jsoup.nodes.Element;
|
||||||
import org.jsoup.select.Elements;
|
import org.jsoup.select.Elements;
|
||||||
|
import org.schabi.newpipe.extractor.MultiInfoItemsCollector;
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItemsCollector;
|
import org.schabi.newpipe.extractor.channel.ChannelInfoItemsCollector;
|
||||||
import org.schabi.newpipe.extractor.downloader.Downloader;
|
import org.schabi.newpipe.extractor.downloader.Downloader;
|
||||||
@ -16,6 +17,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
|||||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
|
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
|
||||||
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudChannelInfoItemExtractor;
|
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudChannelInfoItemExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudPlaylistInfoItemExtractor;
|
||||||
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudStreamInfoItemExtractor;
|
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudStreamInfoItemExtractor;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
||||||
import org.schabi.newpipe.extractor.utils.JsonUtils;
|
import org.schabi.newpipe.extractor.utils.JsonUtils;
|
||||||
@ -300,6 +302,54 @@ public final class SoundcloudParsingHelper {
|
|||||||
return getStreamsFromApi(collector, apiUrl, false);
|
return getStreamsFromApi(collector, apiUrl, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getInfoItemsFromApi(final MultiInfoItemsCollector collector,
|
||||||
|
final String apiUrl) throws ReCaptchaException,
|
||||||
|
ParsingException, IOException {
|
||||||
|
final Response response = NewPipe.getDownloader().get(apiUrl, SoundCloud.getLocalization());
|
||||||
|
if (response.responseCode() >= 400) {
|
||||||
|
throw new IOException("Could not get streams from API, HTTP "
|
||||||
|
+ response.responseCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
final JsonObject responseObject;
|
||||||
|
try {
|
||||||
|
responseObject = JsonParser.object().from(response.responseBody());
|
||||||
|
} catch (final JsonParserException e) {
|
||||||
|
throw new ParsingException("Could not parse json response", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
responseObject.getArray("collection")
|
||||||
|
.stream()
|
||||||
|
.filter(JsonObject.class::isInstance)
|
||||||
|
.map(JsonObject.class::cast)
|
||||||
|
.forEach(searchResult -> {
|
||||||
|
final 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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
String nextPageUrl;
|
||||||
|
try {
|
||||||
|
nextPageUrl = responseObject.getString("next_href");
|
||||||
|
if (!nextPageUrl.contains("client_id=")) {
|
||||||
|
nextPageUrl += "&client_id=" + SoundcloudParsingHelper.clientId();
|
||||||
|
}
|
||||||
|
} catch (final Exception ignored) {
|
||||||
|
nextPageUrl = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return nextPageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static String getUploaderUrl(final JsonObject object) {
|
public static String getUploaderUrl(final JsonObject object) {
|
||||||
final String url = object.getObject("user").getString("permalink_url", "");
|
final String url = object.getObject("user").getString("permalink_url", "");
|
||||||
@ -312,6 +362,7 @@ public final class SoundcloudParsingHelper {
|
|||||||
return replaceHttpWithHttps(url);
|
return replaceHttpWithHttps(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public static String getUploaderName(final JsonObject object) {
|
public static String getUploaderName(final JsonObject object) {
|
||||||
return object.getObject("user").getString("username", "");
|
return object.getObject("user").getString("username", "");
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import static java.util.Arrays.asList;
|
|||||||
|
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabExtractor;
|
||||||
import org.schabi.newpipe.extractor.comments.CommentsExtractor;
|
import org.schabi.newpipe.extractor.comments.CommentsExtractor;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
import org.schabi.newpipe.extractor.kiosk.KioskList;
|
import org.schabi.newpipe.extractor.kiosk.KioskList;
|
||||||
@ -19,6 +20,7 @@ import org.schabi.newpipe.extractor.localization.ContentCountry;
|
|||||||
import org.schabi.newpipe.extractor.playlist.PlaylistExtractor;
|
import org.schabi.newpipe.extractor.playlist.PlaylistExtractor;
|
||||||
import org.schabi.newpipe.extractor.search.SearchExtractor;
|
import org.schabi.newpipe.extractor.search.SearchExtractor;
|
||||||
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudChannelExtractor;
|
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudChannelExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudChannelTabExtractor;
|
||||||
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudChartsExtractor;
|
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudChartsExtractor;
|
||||||
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudCommentsExtractor;
|
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudCommentsExtractor;
|
||||||
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudPlaylistExtractor;
|
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudPlaylistExtractor;
|
||||||
@ -27,6 +29,7 @@ import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudStr
|
|||||||
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudSubscriptionExtractor;
|
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudSubscriptionExtractor;
|
||||||
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudSuggestionExtractor;
|
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudSuggestionExtractor;
|
||||||
import org.schabi.newpipe.extractor.services.soundcloud.linkHandler.SoundcloudChannelLinkHandlerFactory;
|
import org.schabi.newpipe.extractor.services.soundcloud.linkHandler.SoundcloudChannelLinkHandlerFactory;
|
||||||
|
import org.schabi.newpipe.extractor.services.soundcloud.linkHandler.SoundcloudChannelTabLinkHandlerFactory;
|
||||||
import org.schabi.newpipe.extractor.services.soundcloud.linkHandler.SoundcloudChartsLinkHandlerFactory;
|
import org.schabi.newpipe.extractor.services.soundcloud.linkHandler.SoundcloudChartsLinkHandlerFactory;
|
||||||
import org.schabi.newpipe.extractor.services.soundcloud.linkHandler.SoundcloudCommentsLinkHandlerFactory;
|
import org.schabi.newpipe.extractor.services.soundcloud.linkHandler.SoundcloudCommentsLinkHandlerFactory;
|
||||||
import org.schabi.newpipe.extractor.services.soundcloud.linkHandler.SoundcloudPlaylistLinkHandlerFactory;
|
import org.schabi.newpipe.extractor.services.soundcloud.linkHandler.SoundcloudPlaylistLinkHandlerFactory;
|
||||||
@ -50,7 +53,7 @@ public class SoundcloudService extends StreamingService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SearchQueryHandlerFactory getSearchQHFactory() {
|
public SearchQueryHandlerFactory getSearchQHFactory() {
|
||||||
return new SoundcloudSearchQueryHandlerFactory();
|
return SoundcloudSearchQueryHandlerFactory.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -63,6 +66,11 @@ public class SoundcloudService extends StreamingService {
|
|||||||
return SoundcloudChannelLinkHandlerFactory.getInstance();
|
return SoundcloudChannelLinkHandlerFactory.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListLinkHandlerFactory getChannelTabLHFactory() {
|
||||||
|
return SoundcloudChannelTabLinkHandlerFactory.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListLinkHandlerFactory getPlaylistLHFactory() {
|
public ListLinkHandlerFactory getPlaylistLHFactory() {
|
||||||
return SoundcloudPlaylistLinkHandlerFactory.getInstance();
|
return SoundcloudPlaylistLinkHandlerFactory.getInstance();
|
||||||
@ -86,6 +94,11 @@ public class SoundcloudService extends StreamingService {
|
|||||||
return new SoundcloudChannelExtractor(this, linkHandler);
|
return new SoundcloudChannelExtractor(this, linkHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelTabExtractor getChannelTabExtractor(final ListLinkHandler linkHandler) {
|
||||||
|
return new SoundcloudChannelTabExtractor(this, linkHandler);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlaylistExtractor getPlaylistExtractor(final ListLinkHandler linkHandler) {
|
public PlaylistExtractor getPlaylistExtractor(final ListLinkHandler linkHandler) {
|
||||||
return new SoundcloudPlaylistExtractor(this, linkHandler);
|
return new SoundcloudPlaylistExtractor(this, linkHandler);
|
||||||
@ -103,14 +116,15 @@ public class SoundcloudService extends StreamingService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KioskList getKioskList() throws ExtractionException {
|
public KioskList getKioskList() throws ExtractionException {
|
||||||
final KioskList.KioskExtractorFactory chartsFactory = (streamingService, url, id) ->
|
|
||||||
new SoundcloudChartsExtractor(SoundcloudService.this,
|
|
||||||
new SoundcloudChartsLinkHandlerFactory().fromUrl(url), id);
|
|
||||||
|
|
||||||
final KioskList list = new KioskList(this);
|
final KioskList list = new KioskList(this);
|
||||||
|
|
||||||
|
final SoundcloudChartsLinkHandlerFactory h =
|
||||||
|
SoundcloudChartsLinkHandlerFactory.getInstance();
|
||||||
|
final KioskList.KioskExtractorFactory chartsFactory = (streamingService, url, id) ->
|
||||||
|
new SoundcloudChartsExtractor(SoundcloudService.this,
|
||||||
|
h.fromUrl(url), id);
|
||||||
|
|
||||||
// add kiosks here e.g.:
|
// add kiosks here e.g.:
|
||||||
final SoundcloudChartsLinkHandlerFactory h = new SoundcloudChartsLinkHandlerFactory();
|
|
||||||
try {
|
try {
|
||||||
list.addKioskEntry(chartsFactory, h, "Top 50");
|
list.addKioskEntry(chartsFactory, h, "Top 50");
|
||||||
list.addKioskEntry(chartsFactory, h, "New & hot");
|
list.addKioskEntry(chartsFactory, h, "New & hot");
|
||||||
|
@ -1,24 +1,23 @@
|
|||||||
package org.schabi.newpipe.extractor.services.soundcloud.extractors;
|
package org.schabi.newpipe.extractor.services.soundcloud.extractors;
|
||||||
|
|
||||||
import static org.schabi.newpipe.extractor.services.soundcloud.SoundcloudParsingHelper.SOUNDCLOUD_API_V2_URL;
|
import static org.schabi.newpipe.extractor.services.soundcloud.SoundcloudParsingHelper.SOUNDCLOUD_API_V2_URL;
|
||||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
|
||||||
|
|
||||||
import com.grack.nanojson.JsonObject;
|
import com.grack.nanojson.JsonObject;
|
||||||
import com.grack.nanojson.JsonParser;
|
import com.grack.nanojson.JsonParser;
|
||||||
import com.grack.nanojson.JsonParserException;
|
import com.grack.nanojson.JsonParserException;
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.Page;
|
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabs;
|
||||||
import org.schabi.newpipe.extractor.downloader.Downloader;
|
import org.schabi.newpipe.extractor.downloader.Downloader;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
|
||||||
import org.schabi.newpipe.extractor.services.soundcloud.SoundcloudParsingHelper;
|
import org.schabi.newpipe.extractor.services.soundcloud.SoundcloudParsingHelper;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
import org.schabi.newpipe.extractor.services.soundcloud.linkHandler.SoundcloudChannelTabLinkHandlerFactory;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
@ -108,34 +107,22 @@ public class SoundcloudChannelExtractor extends ChannelExtractor {
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public InfoItemsPage<StreamInfoItem> getInitialPage() throws ExtractionException {
|
public List<ListLinkHandler> getTabs() throws ParsingException {
|
||||||
try {
|
final String url = getUrl();
|
||||||
final StreamInfoItemsCollector streamInfoItemsCollector =
|
final String urlTracks = url
|
||||||
new StreamInfoItemsCollector(getServiceId());
|
+ SoundcloudChannelTabLinkHandlerFactory.getUrlSuffix(ChannelTabs.TRACKS);
|
||||||
|
final String urlPlaylists = url
|
||||||
|
+ SoundcloudChannelTabLinkHandlerFactory.getUrlSuffix(ChannelTabs.PLAYLISTS);
|
||||||
|
final String urlAlbums = url
|
||||||
|
+ SoundcloudChannelTabLinkHandlerFactory.getUrlSuffix(ChannelTabs.ALBUMS);
|
||||||
|
final String id = getId();
|
||||||
|
|
||||||
final String apiUrl = USERS_ENDPOINT + getId() + "/tracks" + "?client_id="
|
return List.of(
|
||||||
+ SoundcloudParsingHelper.clientId() + "&limit=20" + "&linked_partitioning=1";
|
new ListLinkHandler(urlTracks, urlTracks, id,
|
||||||
|
List.of(ChannelTabs.TRACKS), ""),
|
||||||
final String nextPageUrl = SoundcloudParsingHelper.getStreamsFromApiMinItems(15,
|
new ListLinkHandler(urlPlaylists, urlPlaylists, id,
|
||||||
streamInfoItemsCollector, apiUrl);
|
List.of(ChannelTabs.PLAYLISTS), ""),
|
||||||
|
new ListLinkHandler(urlAlbums, urlAlbums, id,
|
||||||
return new InfoItemsPage<>(streamInfoItemsCollector, new Page(nextPageUrl));
|
List.of(ChannelTabs.ALBUMS), ""));
|
||||||
} catch (final Exception e) {
|
|
||||||
throw new ExtractionException("Could not get next page", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InfoItemsPage<StreamInfoItem> getPage(final Page page) throws IOException,
|
|
||||||
ExtractionException {
|
|
||||||
if (page == null || isNullOrEmpty(page.getUrl())) {
|
|
||||||
throw new IllegalArgumentException("Page doesn't contain an URL");
|
|
||||||
}
|
|
||||||
|
|
||||||
final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
|
|
||||||
final String nextPageUrl = SoundcloudParsingHelper.getStreamsFromApiMinItems(15, collector,
|
|
||||||
page.getUrl());
|
|
||||||
|
|
||||||
return new InfoItemsPage<>(collector, new Page(nextPageUrl));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,76 @@
|
|||||||
|
package org.schabi.newpipe.extractor.services.soundcloud.extractors;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
|
import org.schabi.newpipe.extractor.MultiInfoItemsCollector;
|
||||||
|
import org.schabi.newpipe.extractor.Page;
|
||||||
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
|
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabs;
|
||||||
|
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.ListLinkHandler;
|
||||||
|
import org.schabi.newpipe.extractor.services.soundcloud.SoundcloudParsingHelper;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.schabi.newpipe.extractor.services.soundcloud.SoundcloudParsingHelper.SOUNDCLOUD_API_V2_URL;
|
||||||
|
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||||
|
|
||||||
|
public class SoundcloudChannelTabExtractor extends ChannelTabExtractor {
|
||||||
|
|
||||||
|
private static final String USERS_ENDPOINT = SOUNDCLOUD_API_V2_URL + "users/";
|
||||||
|
|
||||||
|
private final String userId;
|
||||||
|
|
||||||
|
public SoundcloudChannelTabExtractor(final StreamingService service,
|
||||||
|
final ListLinkHandler linkHandler) {
|
||||||
|
super(service, linkHandler);
|
||||||
|
userId = getLinkHandler().getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private String getEndpoint() throws ParsingException {
|
||||||
|
switch (getName()) {
|
||||||
|
case ChannelTabs.TRACKS:
|
||||||
|
return "/tracks";
|
||||||
|
case ChannelTabs.PLAYLISTS:
|
||||||
|
return "/playlists_without_albums";
|
||||||
|
case ChannelTabs.ALBUMS:
|
||||||
|
return "/albums";
|
||||||
|
}
|
||||||
|
throw new ParsingException("Unsupported tab: " + getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFetchPage(@Nonnull final Downloader downloader) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public InfoItemsPage<InfoItem> getInitialPage() throws IOException, ExtractionException {
|
||||||
|
return getPage(new Page(USERS_ENDPOINT + userId + getEndpoint() + "?client_id="
|
||||||
|
+ SoundcloudParsingHelper.clientId() + "&limit=20" + "&linked_partitioning=1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InfoItemsPage<InfoItem> getPage(final Page page)
|
||||||
|
throws IOException, ExtractionException {
|
||||||
|
if (page == null || isNullOrEmpty(page.getUrl())) {
|
||||||
|
throw new IllegalArgumentException("Page doesn't contain an URL");
|
||||||
|
}
|
||||||
|
|
||||||
|
final MultiInfoItemsCollector collector = new MultiInfoItemsCollector(getServiceId());
|
||||||
|
final String nextPageUrl = SoundcloudParsingHelper.getInfoItemsFromApi(
|
||||||
|
collector, page.getUrl());
|
||||||
|
|
||||||
|
return new InfoItemsPage<>(collector, new Page(nextPageUrl));
|
||||||
|
}
|
||||||
|
}
|
@ -23,7 +23,7 @@ public final class SoundcloudChannelLinkHandlerFactory extends ListLinkHandlerFa
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId(final String url) throws ParsingException {
|
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
|
||||||
Utils.checkUrl(URL_PATTERN, url);
|
Utils.checkUrl(URL_PATTERN, url);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -36,7 +36,8 @@ public final class SoundcloudChannelLinkHandlerFactory extends ListLinkHandlerFa
|
|||||||
@Override
|
@Override
|
||||||
public String getUrl(final String id,
|
public String getUrl(final String id,
|
||||||
final List<String> contentFilter,
|
final List<String> contentFilter,
|
||||||
final String sortFilter) throws ParsingException {
|
final String sortFilter)
|
||||||
|
throws ParsingException, UnsupportedOperationException {
|
||||||
try {
|
try {
|
||||||
return SoundcloudParsingHelper.resolveUrlWithEmbedPlayer(
|
return SoundcloudParsingHelper.resolveUrlWithEmbedPlayer(
|
||||||
"https://api.soundcloud.com/users/" + id);
|
"https://api.soundcloud.com/users/" + id);
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
package org.schabi.newpipe.extractor.services.soundcloud.linkHandler;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabs;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.UnsupportedTabException;
|
||||||
|
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public final class SoundcloudChannelTabLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||||
|
private static final SoundcloudChannelTabLinkHandlerFactory INSTANCE
|
||||||
|
= new SoundcloudChannelTabLinkHandlerFactory();
|
||||||
|
|
||||||
|
private SoundcloudChannelTabLinkHandlerFactory() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SoundcloudChannelTabLinkHandlerFactory getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static String getUrlSuffix(final String tab) throws UnsupportedOperationException {
|
||||||
|
switch (tab) {
|
||||||
|
case ChannelTabs.TRACKS:
|
||||||
|
return "/tracks";
|
||||||
|
case ChannelTabs.PLAYLISTS:
|
||||||
|
return "/sets";
|
||||||
|
case ChannelTabs.ALBUMS:
|
||||||
|
return "/albums";
|
||||||
|
}
|
||||||
|
throw new UnsupportedTabException(tab);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId(final String url) throws ParsingException {
|
||||||
|
return SoundcloudChannelLinkHandlerFactory.getInstance().getId(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUrl(final String id,
|
||||||
|
final List<String> contentFilter,
|
||||||
|
final String sortFilter) throws ParsingException {
|
||||||
|
return SoundcloudChannelLinkHandlerFactory.getInstance().getUrl(id)
|
||||||
|
+ getUrlSuffix(contentFilter.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onAcceptUrl(final String url) throws ParsingException {
|
||||||
|
return SoundcloudChannelLinkHandlerFactory.getInstance().onAcceptUrl(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getAvailableContentFilter() {
|
||||||
|
return new String[] {
|
||||||
|
ChannelTabs.TRACKS,
|
||||||
|
ChannelTabs.PLAYLISTS,
|
||||||
|
ChannelTabs.ALBUMS,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -1,18 +1,30 @@
|
|||||||
package org.schabi.newpipe.extractor.services.soundcloud.linkHandler;
|
package org.schabi.newpipe.extractor.services.soundcloud.linkHandler;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
|
||||||
import org.schabi.newpipe.extractor.utils.Parser;
|
import org.schabi.newpipe.extractor.utils.Parser;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SoundcloudChartsLinkHandlerFactory extends ListLinkHandlerFactory {
|
public final class SoundcloudChartsLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||||
|
|
||||||
|
private static final SoundcloudChartsLinkHandlerFactory INSTANCE =
|
||||||
|
new SoundcloudChartsLinkHandlerFactory();
|
||||||
|
|
||||||
private static final String TOP_URL_PATTERN =
|
private static final String TOP_URL_PATTERN =
|
||||||
"^https?://(www\\.|m\\.)?soundcloud.com/charts(/top)?/?([#?].*)?$";
|
"^https?://(www\\.|m\\.)?soundcloud.com/charts(/top)?/?([#?].*)?$";
|
||||||
private static final String URL_PATTERN =
|
private static final String URL_PATTERN =
|
||||||
"^https?://(www\\.|m\\.)?soundcloud.com/charts(/top|/new)?/?([#?].*)?$";
|
"^https?://(www\\.|m\\.)?soundcloud.com/charts(/top|/new)?/?([#?].*)?$";
|
||||||
|
|
||||||
|
private SoundcloudChartsLinkHandlerFactory() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SoundcloudChartsLinkHandlerFactory getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId(final String url) {
|
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
|
||||||
if (Parser.isMatch(TOP_URL_PATTERN, url.toLowerCase())) {
|
if (Parser.isMatch(TOP_URL_PATTERN, url.toLowerCase())) {
|
||||||
return "Top 50";
|
return "Top 50";
|
||||||
} else {
|
} else {
|
||||||
@ -23,7 +35,8 @@ public class SoundcloudChartsLinkHandlerFactory extends ListLinkHandlerFactory {
|
|||||||
@Override
|
@Override
|
||||||
public String getUrl(final String id,
|
public String getUrl(final String id,
|
||||||
final List<String> contentFilter,
|
final List<String> contentFilter,
|
||||||
final String sortFilter) {
|
final String sortFilter)
|
||||||
|
throws ParsingException, UnsupportedOperationException {
|
||||||
if (id.equals("Top 50")) {
|
if (id.equals("Top 50")) {
|
||||||
return "https://soundcloud.com/charts/top";
|
return "https://soundcloud.com/charts/top";
|
||||||
} else {
|
} else {
|
||||||
|
@ -24,7 +24,8 @@ public final class SoundcloudCommentsLinkHandlerFactory extends ListLinkHandlerF
|
|||||||
@Override
|
@Override
|
||||||
public String getUrl(final String id,
|
public String getUrl(final String id,
|
||||||
final List<String> contentFilter,
|
final List<String> contentFilter,
|
||||||
final String sortFilter) throws ParsingException {
|
final String sortFilter)
|
||||||
|
throws ParsingException, UnsupportedOperationException {
|
||||||
try {
|
try {
|
||||||
return "https://api-v2.soundcloud.com/tracks/" + id + "/comments" + "?client_id="
|
return "https://api-v2.soundcloud.com/tracks/" + id + "/comments" + "?client_id="
|
||||||
+ clientId() + "&threaded=0" + "&filter_replies=1";
|
+ clientId() + "&threaded=0" + "&filter_replies=1";
|
||||||
@ -37,7 +38,7 @@ public final class SoundcloudCommentsLinkHandlerFactory extends ListLinkHandlerF
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId(final String url) throws ParsingException {
|
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
|
||||||
// Delegation to avoid duplicate code, as we need the same id
|
// Delegation to avoid duplicate code, as we need the same id
|
||||||
return SoundcloudStreamLinkHandlerFactory.getInstance().getId(url);
|
return SoundcloudStreamLinkHandlerFactory.getInstance().getId(url);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ public final class SoundcloudPlaylistLinkHandlerFactory extends ListLinkHandlerF
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId(final String url) throws ParsingException {
|
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
|
||||||
Utils.checkUrl(URL_PATTERN, url);
|
Utils.checkUrl(URL_PATTERN, url);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -37,7 +37,7 @@ public final class SoundcloudPlaylistLinkHandlerFactory extends ListLinkHandlerF
|
|||||||
public String getUrl(final String id,
|
public String getUrl(final String id,
|
||||||
final List<String> contentFilter,
|
final List<String> contentFilter,
|
||||||
final String sortFilter)
|
final String sortFilter)
|
||||||
throws ParsingException {
|
throws ParsingException, UnsupportedOperationException {
|
||||||
try {
|
try {
|
||||||
return SoundcloudParsingHelper.resolveUrlWithEmbedPlayer(
|
return SoundcloudParsingHelper.resolveUrlWithEmbedPlayer(
|
||||||
"https://api.soundcloud.com/playlists/" + id);
|
"https://api.soundcloud.com/playlists/" + id);
|
||||||
|
@ -13,7 +13,10 @@ import java.io.IOException;
|
|||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SoundcloudSearchQueryHandlerFactory extends SearchQueryHandlerFactory {
|
public final class SoundcloudSearchQueryHandlerFactory extends SearchQueryHandlerFactory {
|
||||||
|
|
||||||
|
private static final SoundcloudSearchQueryHandlerFactory INSTANCE =
|
||||||
|
new SoundcloudSearchQueryHandlerFactory();
|
||||||
|
|
||||||
public static final String TRACKS = "tracks";
|
public static final String TRACKS = "tracks";
|
||||||
public static final String USERS = "users";
|
public static final String USERS = "users";
|
||||||
@ -22,11 +25,18 @@ public class SoundcloudSearchQueryHandlerFactory extends SearchQueryHandlerFacto
|
|||||||
|
|
||||||
public static final int ITEMS_PER_PAGE = 10;
|
public static final int ITEMS_PER_PAGE = 10;
|
||||||
|
|
||||||
|
private SoundcloudSearchQueryHandlerFactory() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SoundcloudSearchQueryHandlerFactory getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUrl(final String id,
|
public String getUrl(final String id,
|
||||||
final List<String> contentFilter,
|
final List<String> contentFilter,
|
||||||
final String sortFilter)
|
final String sortFilter)
|
||||||
throws ParsingException {
|
throws ParsingException, UnsupportedOperationException {
|
||||||
try {
|
try {
|
||||||
String url = SOUNDCLOUD_API_V2_URL + "search";
|
String url = SOUNDCLOUD_API_V2_URL + "search";
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ public final class SoundcloudStreamLinkHandlerFactory extends LinkHandlerFactory
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUrl(final String id) throws ParsingException {
|
public String getUrl(final String id) throws ParsingException, UnsupportedOperationException {
|
||||||
try {
|
try {
|
||||||
return SoundcloudParsingHelper.resolveUrlWithEmbedPlayer(
|
return SoundcloudParsingHelper.resolveUrlWithEmbedPlayer(
|
||||||
"https://api.soundcloud.com/tracks/" + id);
|
"https://api.soundcloud.com/tracks/" + id);
|
||||||
@ -31,7 +31,7 @@ public final class SoundcloudStreamLinkHandlerFactory extends LinkHandlerFactory
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId(final String url) throws ParsingException {
|
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
|
||||||
if (Parser.isMatch(API_URL_PATTERN, url)) {
|
if (Parser.isMatch(API_URL_PATTERN, url)) {
|
||||||
return Parser.matchGroup1(API_URL_PATTERN, url);
|
return Parser.matchGroup1(API_URL_PATTERN, url);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user