[Bandcamp] Add tabs support for artists

Support of tracks and albums has been added for artists.

Also use the singleton pattern and add the declaration of the
UnsupportedOperationException exception to the service's LinkHandlers and
improved some code in the files changed.

Co-authored-by: ThetaDev <t.testboy@gmail.com>
Co-authored-by: Stypox <stypox@pm.me>
This commit is contained in:
AudricV 2023-06-29 21:52:24 +02:00 committed by Stypox
parent 1e8474b22d
commit 6f7d1f079f
No known key found for this signature in database
GPG Key ID: 4BDF1B40A49FDD23
11 changed files with 405 additions and 64 deletions

View File

@ -12,6 +12,7 @@ import static org.schabi.newpipe.extractor.services.bandcamp.extractors.Bandcamp
import org.schabi.newpipe.extractor.StreamingService;
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.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.kiosk.KioskList;
@ -19,11 +20,13 @@ import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
import org.schabi.newpipe.extractor.linkhandler.ReadyChannelTabListLinkHandler;
import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandler;
import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandlerFactory;
import org.schabi.newpipe.extractor.playlist.PlaylistExtractor;
import org.schabi.newpipe.extractor.search.SearchExtractor;
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampChannelExtractor;
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampChannelTabExtractor;
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampCommentsExtractor;
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper;
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampFeaturedExtractor;
@ -34,6 +37,7 @@ import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampSearchE
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampStreamExtractor;
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampSuggestionExtractor;
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampChannelLinkHandlerFactory;
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampChannelTabLinkHandlerFactory;
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampCommentsLinkHandlerFactory;
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampFeaturedLinkHandlerFactory;
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampPlaylistLinkHandlerFactory;
@ -58,27 +62,32 @@ public class BandcampService extends StreamingService {
@Override
public LinkHandlerFactory getStreamLHFactory() {
return new BandcampStreamLinkHandlerFactory();
return BandcampStreamLinkHandlerFactory.getInstance();
}
@Override
public ListLinkHandlerFactory getChannelLHFactory() {
return new BandcampChannelLinkHandlerFactory();
return BandcampChannelLinkHandlerFactory.getInstance();
}
@Override
public ListLinkHandlerFactory getChannelTabLHFactory() {
return BandcampChannelTabLinkHandlerFactory.getInstance();
}
@Override
public ListLinkHandlerFactory getPlaylistLHFactory() {
return new BandcampPlaylistLinkHandlerFactory();
return BandcampPlaylistLinkHandlerFactory.getInstance();
}
@Override
public SearchQueryHandlerFactory getSearchQHFactory() {
return new BandcampSearchQueryHandlerFactory();
return BandcampSearchQueryHandlerFactory.getInstance();
}
@Override
public ListLinkHandlerFactory getCommentsLHFactory() {
return new BandcampCommentsLinkHandlerFactory();
return BandcampCommentsLinkHandlerFactory.getInstance();
}
@Override
@ -98,27 +107,27 @@ public class BandcampService extends StreamingService {
@Override
public KioskList getKioskList() throws ExtractionException {
final KioskList kioskList = new KioskList(this);
final ListLinkHandlerFactory h = BandcampFeaturedLinkHandlerFactory.getInstance();
try {
kioskList.addKioskEntry(
(streamingService, url, kioskId) -> new BandcampFeaturedExtractor(
BandcampService.this,
new BandcampFeaturedLinkHandlerFactory().fromUrl(FEATURED_API_URL),
h.fromUrl(FEATURED_API_URL),
kioskId
),
new BandcampFeaturedLinkHandlerFactory(),
h,
KIOSK_FEATURED
);
kioskList.addKioskEntry(
(streamingService, url, kioskId) -> new BandcampRadioExtractor(
BandcampService.this,
new BandcampFeaturedLinkHandlerFactory().fromUrl(RADIO_API_URL),
h.fromUrl(RADIO_API_URL),
kioskId
),
new BandcampFeaturedLinkHandlerFactory(),
h,
KIOSK_RADIO
);
@ -136,6 +145,15 @@ public class BandcampService extends StreamingService {
return new BandcampChannelExtractor(this, linkHandler);
}
@Override
public ChannelTabExtractor getChannelTabExtractor(final ListLinkHandler linkHandler) {
if (linkHandler instanceof ReadyChannelTabListLinkHandler) {
return ((ReadyChannelTabListLinkHandler) linkHandler).getChannelTabExtractor(this);
} else {
return new BandcampChannelTabExtractor(this, linkHandler);
}
}
@Override
public PlaylistExtractor getPlaylistExtractor(final ListLinkHandler linkHandler) {
return new BandcampPlaylistExtractor(this, linkHandler);

View File

@ -0,0 +1,55 @@
package org.schabi.newpipe.extractor.services.bandcamp.extractors;
import com.grack.nanojson.JsonObject;
import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItemExtractor;
public class BandcampAlbumInfoItemExtractor implements PlaylistInfoItemExtractor {
private final JsonObject albumInfoItem;
private final String uploaderUrl;
public BandcampAlbumInfoItemExtractor(final JsonObject albumInfoItem,
final String uploaderUrl) {
this.albumInfoItem = albumInfoItem;
this.uploaderUrl = uploaderUrl;
}
@Override
public String getName() throws ParsingException {
return albumInfoItem.getString("title");
}
@Override
public String getUrl() throws ParsingException {
return BandcampExtractorHelper.getStreamUrlFromIds(
albumInfoItem.getLong("band_id"),
albumInfoItem.getLong("item_id"),
albumInfoItem.getString("item_type"));
}
@Override
public String getThumbnailUrl() throws ParsingException {
return BandcampExtractorHelper.getImageUrl(albumInfoItem.getLong("art_id"), true);
}
@Override
public String getUploaderName() throws ParsingException {
return albumInfoItem.getString("band_name");
}
@Override
public String getUploaderUrl() {
return uploaderUrl;
}
@Override
public boolean isUploaderVerified() {
return false;
}
@Override
public long getStreamCount() {
return ListExtractor.ITEM_COUNT_UNKNOWN;
}
}

View File

@ -8,19 +8,22 @@ import com.grack.nanojson.JsonArray;
import com.grack.nanojson.JsonObject;
import org.jsoup.Jsoup;
import org.schabi.newpipe.extractor.Page;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabExtractor;
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.exceptions.ReCaptchaException;
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabs;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
import org.schabi.newpipe.extractor.services.bandcamp.extractors.streaminfoitem.BandcampDiscographStreamInfoItemExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
import org.schabi.newpipe.extractor.linkhandler.ReadyChannelTabListLinkHandler;
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampChannelTabLinkHandlerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
@ -52,8 +55,8 @@ public class BandcampChannelExtractor extends ChannelExtractor {
*/
try {
final String html = getDownloader()
.get(replaceHttpWithHttps(channelInfo.getString("bandcamp_url")))
.responseBody();
.get(replaceHttpWithHttps(channelInfo.getString("bandcamp_url")))
.responseBody();
return Stream.of(Jsoup.parse(html).getElementById("customHeader"))
.filter(Objects::nonNull)
@ -107,29 +110,47 @@ public class BandcampChannelExtractor extends ChannelExtractor {
@Nonnull
@Override
public InfoItemsPage<StreamInfoItem> getInitialPage() throws ParsingException {
final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
public List<ListLinkHandler> getTabs() throws ParsingException {
final JsonArray discography = channelInfo.getArray("discography");
final TabExtractorBuilder builder = new TabExtractorBuilder(discography);
for (int i = 0; i < discography.size(); i++) {
// A discograph is as an item appears in a discography
final JsonObject discograph = discography.getObject(i);
final List<ListLinkHandler> tabs = new ArrayList<>();
if (!discograph.getString("item_type").equals("track")) {
boolean foundTrackItem = false;
boolean foundAlbumItem = false;
for (final Object discographyItem : discography) {
if (foundTrackItem && foundAlbumItem) {
break;
}
if (!(discographyItem instanceof JsonObject)) {
continue;
}
collector.commit(new BandcampDiscographStreamInfoItemExtractor(discograph, getUrl()));
final JsonObject discographyJsonItem = (JsonObject) discographyItem;
final String itemType = discographyJsonItem.getString("item_type");
if (!foundTrackItem && "track".equals(itemType)) {
foundTrackItem = true;
tabs.add(new ReadyChannelTabListLinkHandler(getUrl()
+ BandcampChannelTabLinkHandlerFactory.getUrlSuffix(ChannelTabs.TRACKS),
getId(),
ChannelTabs.TRACKS,
builder));
}
if (!foundAlbumItem && "album".equals(itemType)) {
foundAlbumItem = true;
tabs.add(new ReadyChannelTabListLinkHandler(getUrl()
+ BandcampChannelTabLinkHandlerFactory.getUrlSuffix(ChannelTabs.ALBUMS),
getId(),
ChannelTabs.ALBUMS,
builder));
}
}
return new InfoItemsPage<>(collector, null);
}
@Override
public InfoItemsPage<StreamInfoItem> getPage(final Page page) {
return null;
return Collections.unmodifiableList(tabs);
}
@Override
@ -143,4 +164,20 @@ public class BandcampChannelExtractor extends ChannelExtractor {
public String getName() {
return channelInfo.getString("name");
}
private static final class TabExtractorBuilder
implements ReadyChannelTabListLinkHandler.ChannelTabExtractorBuilder {
private final JsonArray discography;
TabExtractorBuilder(final JsonArray discography) {
this.discography = discography;
}
@Nonnull
@Override
public ChannelTabExtractor build(@Nonnull final StreamingService service,
@Nonnull final ListLinkHandler linkHandler) {
return BandcampChannelTabExtractor.fromDiscography(service, linkHandler, discography);
}
}
}

View File

@ -0,0 +1,95 @@
package org.schabi.newpipe.extractor.services.bandcamp.extractors;
import com.grack.nanojson.JsonArray;
import com.grack.nanojson.JsonObject;
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.bandcamp.extractors.streaminfoitem.BandcampDiscographStreamInfoItemExtractor;
import javax.annotation.Nonnull;
import java.io.IOException;
public class BandcampChannelTabExtractor extends ChannelTabExtractor {
private JsonArray discography;
private final String filter;
public BandcampChannelTabExtractor(final StreamingService service,
final ListLinkHandler linkHandler) {
super(service, linkHandler);
final String tab = linkHandler.getContentFilters().get(0);
switch (tab) {
case ChannelTabs.TRACKS:
filter = "track";
break;
case ChannelTabs.ALBUMS:
filter = "album";
break;
default:
throw new IllegalArgumentException("Unsupported channel tab: " + tab);
}
}
public static BandcampChannelTabExtractor fromDiscography(final StreamingService service,
final ListLinkHandler linkHandler,
final JsonArray discography) {
final BandcampChannelTabExtractor tabExtractor =
new BandcampChannelTabExtractor(service, linkHandler);
tabExtractor.discography = discography;
return tabExtractor;
}
@Override
public void onFetchPage(@Nonnull final Downloader downloader) throws ParsingException {
if (discography == null) {
discography = BandcampExtractorHelper.getArtistDetails(getId())
.getArray("discography");
}
}
@Nonnull
@Override
public InfoItemsPage<InfoItem> getInitialPage() throws IOException, ExtractionException {
final MultiInfoItemsCollector collector = new MultiInfoItemsCollector(getServiceId());
for (final Object discograph : discography) {
// A discograph is as an item appears in a discography
if (!(discograph instanceof JsonObject)) {
continue;
}
final JsonObject discographJsonObject = (JsonObject) discograph;
final String itemType = discographJsonObject.getString("item_type", "");
if (!itemType.equals(filter)) {
continue;
}
switch (itemType) {
case "track":
collector.commit(new BandcampDiscographStreamInfoItemExtractor(
discographJsonObject, getUrl()));
break;
case "album":
collector.commit(new BandcampAlbumInfoItemExtractor(
discographJsonObject, getUrl()));
break;
}
}
return new InfoItemsPage<>(collector, null);
}
@Override
public InfoItemsPage<InfoItem> getPage(final Page page) {
return null;
}
}

View File

@ -10,6 +10,7 @@ import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper;
import org.schabi.newpipe.extractor.utils.JsonUtils;
import org.schabi.newpipe.extractor.utils.Utils;
import java.io.IOException;
import java.util.List;
@ -17,11 +18,20 @@ import java.util.List;
/**
* Artist do have IDs that are useful
*/
public class BandcampChannelLinkHandlerFactory extends ListLinkHandlerFactory {
public final class BandcampChannelLinkHandlerFactory extends ListLinkHandlerFactory {
private static final BandcampChannelLinkHandlerFactory INSTANCE
= new BandcampChannelLinkHandlerFactory();
private BandcampChannelLinkHandlerFactory() {
}
public static BandcampChannelLinkHandlerFactory getInstance() {
return INSTANCE;
}
@Override
public String getId(final String url) throws ParsingException {
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
try {
final String response = NewPipe.getDownloader().get(url).responseBody();
@ -41,16 +51,13 @@ public class BandcampChannelLinkHandlerFactory extends ListLinkHandlerFactory {
*/
@Override
public String getUrl(final String id, final List<String> contentFilter, final String sortFilter)
throws ParsingException {
try {
return BandcampExtractorHelper.getArtistDetails(id)
.getString("bandcamp_url")
.replace("http://", "https://");
} catch (final NullPointerException e) {
throws ParsingException, UnsupportedOperationException {
final JsonObject artistDetails = BandcampExtractorHelper.getArtistDetails(id);
if (artistDetails.getBoolean("error")) {
throw new ParsingException(
"JSON does not contain URL (invalid id?) or is otherwise invalid", e);
"JSON does not contain a channel URL (invalid id?) or is otherwise invalid");
}
return Utils.replaceHttpWithHttps(artistDetails.getString("bandcamp_url"));
}
/**
@ -61,22 +68,21 @@ public class BandcampChannelLinkHandlerFactory extends ListLinkHandlerFactory {
final String lowercaseUrl = url.toLowerCase();
// https: | | artist.bandcamp.com | releases
// 0 1 2 3
// https: | | artist.bandcamp.com | releases - music - album - track ( | name)
// 0 1 2 3 (4)
final String[] splitUrl = lowercaseUrl.split("/");
// URL is too short
if (splitUrl.length < 3) {
if (splitUrl.length != 3 && splitUrl.length != 4) {
return false;
}
// Must have "releases" or "music" as segment after url or none at all
if (splitUrl.length > 3 && !(
splitUrl[3].equals("releases") || splitUrl[3].equals("music")
)) {
// Must have "releases", "music", "album" or "track" as segment after URL or none at all
if (splitUrl.length == 4 && !(splitUrl[3].equals("releases")
|| splitUrl[3].equals("music")
|| splitUrl[3].equals("album")
|| splitUrl[3].equals("track"))) {
return false;
} else {
if (splitUrl[2].equals("daily.bandcamp.com")) {
// Refuse links to daily.bandcamp.com as that is not an artist

View File

@ -0,0 +1,72 @@
package org.schabi.newpipe.extractor.services.bandcamp.linkHandler;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabs;
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 BandcampChannelTabLinkHandlerFactory extends ListLinkHandlerFactory {
private static final BandcampChannelTabLinkHandlerFactory INSTANCE
= new BandcampChannelTabLinkHandlerFactory();
private BandcampChannelTabLinkHandlerFactory() {
}
public static BandcampChannelTabLinkHandlerFactory getInstance() {
return INSTANCE;
}
/**
* Get a tab's URL suffix.
*
* <p>
* These URLs don't actually exist on the Bandcamp website, as both albums and tracks are
* listed on the main page, but redirect to the main page, which is perfect for us as we need a
* unique URL for each tab.
* </p>
*
* @param tab the tab value, which must not be null
* @return a URL suffix
* @throws UnsupportedTabException if the tab is not supported
*/
@Nonnull
public static String getUrlSuffix(@Nonnull final String tab) throws UnsupportedTabException {
switch (tab) {
case ChannelTabs.TRACKS:
return "/track";
case ChannelTabs.ALBUMS:
return "/album";
}
throw new UnsupportedTabException(tab);
}
@Override
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
return BandcampChannelLinkHandlerFactory.getInstance().getId(url);
}
@Override
public String getUrl(final String id, final List<String> contentFilter, final String sortFilter)
throws ParsingException, UnsupportedOperationException {
return BandcampChannelLinkHandlerFactory.getInstance().getUrl(id)
+ getUrlSuffix(contentFilter.get(0));
}
@Override
public boolean onAcceptUrl(final String url) throws ParsingException {
return BandcampChannelLinkHandlerFactory.getInstance().onAcceptUrl(url);
}
@Override
public String[] getAvailableContentFilter() {
return new String[]{
ChannelTabs.TRACKS,
ChannelTabs.ALBUMS,
};
}
}

View File

@ -10,10 +10,20 @@ import java.util.List;
* Like in {@link BandcampStreamLinkHandlerFactory}, tracks have no meaningful IDs except for
* their URLs
*/
public class BandcampCommentsLinkHandlerFactory extends ListLinkHandlerFactory {
public final class BandcampCommentsLinkHandlerFactory extends ListLinkHandlerFactory {
private static final BandcampCommentsLinkHandlerFactory INSTANCE
= new BandcampCommentsLinkHandlerFactory();
private BandcampCommentsLinkHandlerFactory() {
}
public static BandcampCommentsLinkHandlerFactory getInstance() {
return INSTANCE;
}
@Override
public String getId(final String url) throws ParsingException {
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
return url;
}
@ -35,7 +45,8 @@ public class BandcampCommentsLinkHandlerFactory extends ListLinkHandlerFactory {
@Override
public String getUrl(final String id,
final List<String> contentFilter,
final String sortFilter) throws ParsingException {
final String sortFilter)
throws ParsingException, UnsupportedOperationException {
return id;
}
}

View File

@ -2,6 +2,7 @@
package org.schabi.newpipe.extractor.services.bandcamp.linkHandler;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper;
import org.schabi.newpipe.extractor.utils.Utils;
@ -13,12 +14,23 @@ import static org.schabi.newpipe.extractor.services.bandcamp.extractors.Bandcamp
import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampRadioExtractor.KIOSK_RADIO;
import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampRadioExtractor.RADIO_API_URL;
public class BandcampFeaturedLinkHandlerFactory extends ListLinkHandlerFactory {
public final class BandcampFeaturedLinkHandlerFactory extends ListLinkHandlerFactory {
private static final BandcampFeaturedLinkHandlerFactory INSTANCE =
new BandcampFeaturedLinkHandlerFactory();
private BandcampFeaturedLinkHandlerFactory() {
}
public static BandcampFeaturedLinkHandlerFactory getInstance() {
return INSTANCE;
}
@Override
public String getUrl(final String id,
final List<String> contentFilter,
final String sortFilter) {
final String sortFilter)
throws ParsingException, UnsupportedOperationException {
if (id.equals(KIOSK_FEATURED)) {
return FEATURED_API_URL; // doesn't have a website
} else if (id.equals(KIOSK_RADIO)) {
@ -29,7 +41,7 @@ public class BandcampFeaturedLinkHandlerFactory extends ListLinkHandlerFactory {
}
@Override
public String getId(final String url) {
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
final String fixedUrl = Utils.replaceHttpWithHttps(url);
if (BandcampExtractorHelper.isRadioUrl(fixedUrl) || fixedUrl.equals(RADIO_API_URL)) {
return KIOSK_RADIO;

View File

@ -11,16 +11,28 @@ import java.util.List;
/**
* Just as with streams, the album ids are essentially useless for us.
*/
public class BandcampPlaylistLinkHandlerFactory extends ListLinkHandlerFactory {
public final class BandcampPlaylistLinkHandlerFactory extends ListLinkHandlerFactory {
private static final BandcampPlaylistLinkHandlerFactory INSTANCE
= new BandcampPlaylistLinkHandlerFactory();
private BandcampPlaylistLinkHandlerFactory() {
}
public static BandcampPlaylistLinkHandlerFactory getInstance() {
return INSTANCE;
}
@Override
public String getId(final String url) throws ParsingException {
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
return getUrl(url);
}
@Override
public String getUrl(final String url,
final List<String> contentFilter,
final String sortFilter) throws ParsingException {
final String sortFilter)
throws ParsingException, UnsupportedOperationException {
return url;
}

View File

@ -11,11 +11,23 @@ import org.schabi.newpipe.extractor.utils.Utils;
import java.io.UnsupportedEncodingException;
import java.util.List;
public class BandcampSearchQueryHandlerFactory extends SearchQueryHandlerFactory {
public final class BandcampSearchQueryHandlerFactory extends SearchQueryHandlerFactory {
private static final BandcampSearchQueryHandlerFactory INSTANCE
= new BandcampSearchQueryHandlerFactory();
private BandcampSearchQueryHandlerFactory() {
}
public static BandcampSearchQueryHandlerFactory getInstance() {
return INSTANCE;
}
@Override
public String getUrl(final String query,
final List<String> contentFilter,
final String sortFilter) throws ParsingException {
final String sortFilter)
throws ParsingException, UnsupportedOperationException {
try {
return BASE_URL + "/search?q=" + Utils.encodeUrlUtf8(query) + "&page=1";
} catch (final UnsupportedEncodingException e) {

View File

@ -14,14 +14,24 @@ import static org.schabi.newpipe.extractor.services.bandcamp.extractors.Bandcamp
*
* <p>Radio (bandcamp weekly) shows do have ids.</p>
*/
public class BandcampStreamLinkHandlerFactory extends LinkHandlerFactory {
public final class BandcampStreamLinkHandlerFactory extends LinkHandlerFactory {
private static final BandcampStreamLinkHandlerFactory INSTANCE
= new BandcampStreamLinkHandlerFactory();
private BandcampStreamLinkHandlerFactory() {
}
public static BandcampStreamLinkHandlerFactory getInstance() {
return INSTANCE;
}
/**
* @see BandcampStreamLinkHandlerFactory
*/
@Override
public String getId(final String url) throws ParsingException {
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
if (BandcampExtractorHelper.isRadioUrl(url)) {
return url.split("bandcamp.com/\\?show=")[1];
} else {
@ -34,7 +44,8 @@ public class BandcampStreamLinkHandlerFactory extends LinkHandlerFactory {
* @see BandcampStreamLinkHandlerFactory
*/
@Override
public String getUrl(final String input) {
public String getUrl(final String input)
throws ParsingException, UnsupportedOperationException {
if (input.matches("\\d+")) {
return BASE_URL + "/?show=" + input;
} else {