[Bandcamp] Fix checkstyle issues
This commit is contained in:
parent
08dff33002
commit
3a94839359
|
@ -2,23 +2,6 @@
|
||||||
|
|
||||||
package org.schabi.newpipe.extractor.services.bandcamp;
|
package org.schabi.newpipe.extractor.services.bandcamp;
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
|
||||||
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
|
||||||
import org.schabi.newpipe.extractor.comments.CommentsExtractor;
|
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
|
||||||
import org.schabi.newpipe.extractor.kiosk.KioskList;
|
|
||||||
import org.schabi.newpipe.extractor.linkhandler.*;
|
|
||||||
import org.schabi.newpipe.extractor.playlist.PlaylistExtractor;
|
|
||||||
import org.schabi.newpipe.extractor.search.SearchExtractor;
|
|
||||||
import org.schabi.newpipe.extractor.services.bandcamp.extractors.*;
|
|
||||||
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.*;
|
|
||||||
import org.schabi.newpipe.extractor.stream.StreamExtractor;
|
|
||||||
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
|
|
||||||
import org.schabi.newpipe.extractor.suggestion.SuggestionExtractor;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.AUDIO;
|
import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.AUDIO;
|
||||||
import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.COMMENTS;
|
import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.COMMENTS;
|
||||||
import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper.BASE_URL;
|
import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper.BASE_URL;
|
||||||
|
@ -27,6 +10,41 @@ 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.KIOSK_RADIO;
|
||||||
import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampRadioExtractor.RADIO_API_URL;
|
import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampRadioExtractor.RADIO_API_URL;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
|
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.comments.CommentsExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
|
import org.schabi.newpipe.extractor.kiosk.KioskList;
|
||||||
|
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.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.BandcampCommentsExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper;
|
||||||
|
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampFeaturedExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampPlaylistExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampRadioExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampRadioStreamExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampSearchExtractor;
|
||||||
|
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.BandcampCommentsLinkHandlerFactory;
|
||||||
|
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampFeaturedLinkHandlerFactory;
|
||||||
|
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampPlaylistLinkHandlerFactory;
|
||||||
|
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampSearchQueryHandlerFactory;
|
||||||
|
import org.schabi.newpipe.extractor.services.bandcamp.linkHandler.BandcampStreamLinkHandlerFactory;
|
||||||
|
import org.schabi.newpipe.extractor.stream.StreamExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.suggestion.SuggestionExtractor;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class BandcampService extends StreamingService {
|
public class BandcampService extends StreamingService {
|
||||||
|
|
||||||
public BandcampService(final int id) {
|
public BandcampService(final int id) {
|
||||||
|
@ -81,19 +99,28 @@ public class BandcampService extends StreamingService {
|
||||||
@Override
|
@Override
|
||||||
public KioskList getKioskList() throws ExtractionException {
|
public KioskList getKioskList() throws ExtractionException {
|
||||||
|
|
||||||
KioskList kioskList = new KioskList(this);
|
final KioskList kioskList = new KioskList(this);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
kioskList.addKioskEntry((streamingService, url, kioskId) ->
|
kioskList.addKioskEntry(
|
||||||
new BandcampFeaturedExtractor(
|
(streamingService, url, kioskId) -> new BandcampFeaturedExtractor(
|
||||||
BandcampService.this,
|
BandcampService.this,
|
||||||
new BandcampFeaturedLinkHandlerFactory().fromUrl(FEATURED_API_URL), kioskId),
|
new BandcampFeaturedLinkHandlerFactory().fromUrl(FEATURED_API_URL),
|
||||||
new BandcampFeaturedLinkHandlerFactory(), KIOSK_FEATURED);
|
kioskId
|
||||||
|
),
|
||||||
|
new BandcampFeaturedLinkHandlerFactory(),
|
||||||
|
KIOSK_FEATURED
|
||||||
|
);
|
||||||
|
|
||||||
kioskList.addKioskEntry((streamingService, url, kioskId) ->
|
kioskList.addKioskEntry(
|
||||||
new BandcampRadioExtractor(BandcampService.this,
|
(streamingService, url, kioskId) -> new BandcampRadioExtractor(
|
||||||
new BandcampFeaturedLinkHandlerFactory().fromUrl(RADIO_API_URL), kioskId),
|
BandcampService.this,
|
||||||
new BandcampFeaturedLinkHandlerFactory(), KIOSK_RADIO);
|
new BandcampFeaturedLinkHandlerFactory().fromUrl(RADIO_API_URL),
|
||||||
|
kioskId
|
||||||
|
),
|
||||||
|
new BandcampFeaturedLinkHandlerFactory(),
|
||||||
|
KIOSK_RADIO
|
||||||
|
);
|
||||||
|
|
||||||
kioskList.setDefaultKiosk(KIOSK_FEATURED);
|
kioskList.setDefaultKiosk(KIOSK_FEATURED);
|
||||||
|
|
||||||
|
@ -116,14 +143,14 @@ public class BandcampService extends StreamingService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StreamExtractor getStreamExtractor(final LinkHandler linkHandler) {
|
public StreamExtractor getStreamExtractor(final LinkHandler linkHandler) {
|
||||||
if (BandcampExtractorHelper.isRadioUrl(linkHandler.getUrl()))
|
if (BandcampExtractorHelper.isRadioUrl(linkHandler.getUrl())) {
|
||||||
return new BandcampRadioStreamExtractor(this, linkHandler);
|
return new BandcampRadioStreamExtractor(this, linkHandler);
|
||||||
else
|
}
|
||||||
return new BandcampStreamExtractor(this, linkHandler);
|
return new BandcampStreamExtractor(this, linkHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommentsExtractor getCommentsExtractor(ListLinkHandler linkHandler) {
|
public CommentsExtractor getCommentsExtractor(final ListLinkHandler linkHandler) {
|
||||||
return new BandcampCommentsExtractor(this, linkHandler);
|
return new BandcampCommentsExtractor(this, linkHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ package org.schabi.newpipe.extractor.services.bandcamp.extractors;
|
||||||
|
|
||||||
import com.grack.nanojson.JsonArray;
|
import com.grack.nanojson.JsonArray;
|
||||||
import com.grack.nanojson.JsonObject;
|
import com.grack.nanojson.JsonObject;
|
||||||
|
|
||||||
import org.jsoup.Jsoup;
|
import org.jsoup.Jsoup;
|
||||||
import org.schabi.newpipe.extractor.Page;
|
import org.schabi.newpipe.extractor.Page;
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
|
@ -17,20 +18,24 @@ import org.schabi.newpipe.extractor.services.bandcamp.extractors.streaminfoitem.
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class BandcampChannelExtractor extends ChannelExtractor {
|
public class BandcampChannelExtractor extends ChannelExtractor {
|
||||||
|
|
||||||
private JsonObject channelInfo;
|
private JsonObject channelInfo;
|
||||||
|
|
||||||
public BandcampChannelExtractor(final StreamingService service, final ListLinkHandler linkHandler) {
|
public BandcampChannelExtractor(final StreamingService service,
|
||||||
|
final ListLinkHandler linkHandler) {
|
||||||
super(service, linkHandler);
|
super(service, linkHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getAvatarUrl() {
|
public String getAvatarUrl() {
|
||||||
if (channelInfo.getLong("bio_image_id") == 0) return "";
|
if (channelInfo.getLong("bio_image_id") == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
return BandcampExtractorHelper.getImageUrl(channelInfo.getLong("bio_image_id"), false);
|
return BandcampExtractorHelper.getImageUrl(channelInfo.getLong("bio_image_id"), false);
|
||||||
}
|
}
|
||||||
|
@ -43,7 +48,8 @@ public class BandcampChannelExtractor extends ChannelExtractor {
|
||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
final String html = getDownloader()
|
final String html = getDownloader()
|
||||||
.get(channelInfo.getString("bandcamp_url").replace("http://", "https://"))
|
.get(channelInfo.getString("bandcamp_url")
|
||||||
|
.replace("http://", "https://"))
|
||||||
.responseBody();
|
.responseBody();
|
||||||
|
|
||||||
return Jsoup.parse(html)
|
return Jsoup.parse(html)
|
||||||
|
@ -110,7 +116,9 @@ public class BandcampChannelExtractor extends ChannelExtractor {
|
||||||
// A discograph is as an item appears in a discography
|
// A discograph is as an item appears in a discography
|
||||||
final JsonObject discograph = discography.getObject(i);
|
final JsonObject discograph = discography.getObject(i);
|
||||||
|
|
||||||
if (!discograph.getString("item_type").equals("track")) continue;
|
if (!discograph.getString("item_type").equals("track")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
collector.commit(new BandcampDiscographStreamInfoItemExtractor(discograph, getUrl()));
|
collector.commit(new BandcampDiscographStreamInfoItemExtractor(discograph, getUrl()));
|
||||||
}
|
}
|
||||||
|
@ -119,12 +127,13 @@ public class BandcampChannelExtractor extends ChannelExtractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InfoItemsPage<StreamInfoItem> getPage(Page page) {
|
public InfoItemsPage<StreamInfoItem> getPage(final Page page) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFetchPage(@Nonnull Downloader downloader) throws IOException, ExtractionException {
|
public void onFetchPage(@Nonnull final Downloader downloader)
|
||||||
|
throws IOException, ExtractionException {
|
||||||
channelInfo = BandcampExtractorHelper.getArtistDetails(getId());
|
channelInfo = BandcampExtractorHelper.getArtistDetails(getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,8 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
|
|
||||||
public class BandcampChannelInfoItemExtractor implements ChannelInfoItemExtractor {
|
public class BandcampChannelInfoItemExtractor implements ChannelInfoItemExtractor {
|
||||||
|
|
||||||
private final Element resultInfo, searchResult;
|
private final Element resultInfo;
|
||||||
|
private final Element searchResult;
|
||||||
|
|
||||||
public BandcampChannelInfoItemExtractor(final Element searchResult) {
|
public BandcampChannelInfoItemExtractor(final Element searchResult) {
|
||||||
this.searchResult = searchResult;
|
this.searchResult = searchResult;
|
||||||
|
|
|
@ -21,25 +21,27 @@ public class BandcampCommentsExtractor extends CommentsExtractor {
|
||||||
private Document document;
|
private Document document;
|
||||||
|
|
||||||
|
|
||||||
public BandcampCommentsExtractor(StreamingService service, ListLinkHandler linkHandler) {
|
public BandcampCommentsExtractor(final StreamingService service,
|
||||||
|
final ListLinkHandler linkHandler) {
|
||||||
super(service, linkHandler);
|
super(service, linkHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFetchPage(@Nonnull Downloader downloader) throws IOException, ExtractionException {
|
public void onFetchPage(@Nonnull final Downloader downloader)
|
||||||
String html = downloader.get(getLinkHandler().getUrl()).responseBody();
|
throws IOException, ExtractionException {
|
||||||
document = Jsoup.parse(html);
|
document = Jsoup.parse(downloader.get(getLinkHandler().getUrl()).responseBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public InfoItemsPage<CommentsInfoItem> getInitialPage() throws IOException, ExtractionException {
|
public InfoItemsPage<CommentsInfoItem> getInitialPage()
|
||||||
|
throws IOException, ExtractionException {
|
||||||
|
|
||||||
CommentsInfoItemsCollector collector = new CommentsInfoItemsCollector(getServiceId());
|
final CommentsInfoItemsCollector collector = new CommentsInfoItemsCollector(getServiceId());
|
||||||
|
|
||||||
Elements writings = document.getElementsByClass("writing");
|
final Elements writings = document.getElementsByClass("writing");
|
||||||
|
|
||||||
for (Element writing : writings) {
|
for (final Element writing : writings) {
|
||||||
collector.commit(new BandcampCommentsInfoItemExtractor(writing, getUrl()));
|
collector.commit(new BandcampCommentsInfoItemExtractor(writing, getUrl()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +49,8 @@ public class BandcampCommentsExtractor extends CommentsExtractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InfoItemsPage<CommentsInfoItem> getPage(Page page) throws IOException, ExtractionException {
|
public InfoItemsPage<CommentsInfoItem> getPage(final Page page)
|
||||||
|
throws IOException, ExtractionException {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ public class BandcampCommentsInfoItemExtractor implements CommentsInfoItemExtrac
|
||||||
private final Element writing;
|
private final Element writing;
|
||||||
private final String url;
|
private final String url;
|
||||||
|
|
||||||
public BandcampCommentsInfoItemExtractor(Element writing, String url) {
|
public BandcampCommentsInfoItemExtractor(final Element writing, final String url) {
|
||||||
this.writing = writing;
|
this.writing = writing;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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 com.grack.nanojson.JsonWriter;
|
import com.grack.nanojson.JsonWriter;
|
||||||
|
|
||||||
import org.jsoup.Jsoup;
|
import org.jsoup.Jsoup;
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
|
@ -18,18 +19,21 @@ import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public class BandcampExtractorHelper {
|
public final class BandcampExtractorHelper {
|
||||||
|
|
||||||
public static final String BASE_URL = "https://bandcamp.com";
|
public static final String BASE_URL = "https://bandcamp.com";
|
||||||
public static final String BASE_API_URL = BASE_URL + "/api";
|
public static final String BASE_API_URL = BASE_URL + "/api";
|
||||||
|
|
||||||
|
private BandcampExtractorHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate all these parameters together to the URL of the corresponding album or track
|
* Translate all these parameters together to the URL of the corresponding album or track
|
||||||
* using the mobile API
|
* using the mobile API
|
||||||
*/
|
*/
|
||||||
public static String getStreamUrlFromIds(final long bandId, final long itemId, final String itemType)
|
public static String getStreamUrlFromIds(final long bandId,
|
||||||
throws ParsingException {
|
final long itemId,
|
||||||
|
final String itemType) throws ParsingException {
|
||||||
try {
|
try {
|
||||||
final String jsonString = NewPipe.getDownloader().get(
|
final String jsonString = NewPipe.getDownloader().get(
|
||||||
BASE_API_URL + "/mobile/22/tralbum_details?band_id=" + bandId
|
BASE_API_URL + "/mobile/22/tralbum_details?band_id=" + bandId
|
||||||
|
@ -50,7 +54,7 @@ public class BandcampExtractorHelper {
|
||||||
* <a href=https://notabug.org/fynngodau/bandcampDirect/wiki/rewindBandcamp+%E2%80%93+Fetching+artist+details>
|
* <a href=https://notabug.org/fynngodau/bandcampDirect/wiki/rewindBandcamp+%E2%80%93+Fetching+artist+details>
|
||||||
* More technical info.</a>
|
* More technical info.</a>
|
||||||
*/
|
*/
|
||||||
public static JsonObject getArtistDetails(String id) throws ParsingException {
|
public static JsonObject getArtistDetails(final String id) throws ParsingException {
|
||||||
try {
|
try {
|
||||||
return
|
return
|
||||||
JsonParser.object().from(
|
JsonParser.object().from(
|
||||||
|
@ -91,24 +95,24 @@ public class BandcampExtractorHelper {
|
||||||
public static boolean isSupportedDomain(final String url) throws ParsingException {
|
public static boolean isSupportedDomain(final String url) throws ParsingException {
|
||||||
|
|
||||||
// Accept all bandcamp.com URLs
|
// Accept all bandcamp.com URLs
|
||||||
if (url.toLowerCase().matches("https?://.+\\.bandcamp\\.com(/.*)?")) return true;
|
if (url.toLowerCase().matches("https?://.+\\.bandcamp\\.com(/.*)?")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Test other URLs for whether they contain a footer that links to bandcamp
|
// Test other URLs for whether they contain a footer that links to bandcamp
|
||||||
return Jsoup.parse(
|
return Jsoup.parse(NewPipe.getDownloader().get(url).responseBody())
|
||||||
NewPipe.getDownloader().get(url).responseBody()
|
|
||||||
)
|
|
||||||
.getElementById("pgFt")
|
.getElementById("pgFt")
|
||||||
.getElementById("pgFt-inner")
|
.getElementById("pgFt-inner")
|
||||||
.getElementById("footer-logo-wrapper")
|
.getElementById("footer-logo-wrapper")
|
||||||
.getElementById("footer-logo")
|
.getElementById("footer-logo")
|
||||||
.getElementsByClass("hiddenAccess")
|
.getElementsByClass("hiddenAccess")
|
||||||
.text().equals("Bandcamp");
|
.text().equals("Bandcamp");
|
||||||
} catch (NullPointerException e) {
|
} catch (final NullPointerException e) {
|
||||||
return false;
|
return false;
|
||||||
} catch (IOException | ReCaptchaException e) {
|
} catch (final IOException | ReCaptchaException e) {
|
||||||
throw new ParsingException("Could not determine whether URL is custom domain " +
|
throw new ParsingException("Could not determine whether URL is custom domain "
|
||||||
"(not available? network error?)");
|
+ "(not available? network error?)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,10 +125,10 @@ public class BandcampExtractorHelper {
|
||||||
return url.toLowerCase().matches("https?://bandcamp\\.com/\\?show=\\d+");
|
return url.toLowerCase().matches("https?://bandcamp\\.com/\\?show=\\d+");
|
||||||
}
|
}
|
||||||
|
|
||||||
static DateWrapper parseDate(final String textDate) throws ParsingException {
|
public static DateWrapper parseDate(final String textDate) throws ParsingException {
|
||||||
try {
|
try {
|
||||||
final ZonedDateTime zonedDateTime = ZonedDateTime.parse(
|
final ZonedDateTime zonedDateTime = ZonedDateTime.parse(textDate,
|
||||||
textDate, DateTimeFormatter.ofPattern("dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH));
|
DateTimeFormatter.ofPattern("dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH));
|
||||||
return new DateWrapper(zonedDateTime.toOffsetDateTime(), false);
|
return new DateWrapper(zonedDateTime.toOffsetDateTime(), false);
|
||||||
} catch (final DateTimeException e) {
|
} catch (final DateTimeException e) {
|
||||||
throw new ParsingException("Could not parse date '" + textDate + "'", e);
|
throw new ParsingException("Could not parse date '" + textDate + "'", e);
|
||||||
|
|
|
@ -25,17 +25,20 @@ public class BandcampFeaturedExtractor extends KioskExtractor<PlaylistInfoItem>
|
||||||
|
|
||||||
public static final String KIOSK_FEATURED = "Featured";
|
public static final String KIOSK_FEATURED = "Featured";
|
||||||
public static final String FEATURED_API_URL = BASE_API_URL + "/mobile/24/bootstrap_data";
|
public static final String FEATURED_API_URL = BASE_API_URL + "/mobile/24/bootstrap_data";
|
||||||
public static final String MORE_FEATURED_API_URL = BASE_API_URL + "/mobile/24/feed_older_logged_out";
|
public static final String MORE_FEATURED_API_URL
|
||||||
|
= BASE_API_URL + "/mobile/24/feed_older_logged_out";
|
||||||
|
|
||||||
private JsonObject json;
|
private JsonObject json;
|
||||||
|
|
||||||
public BandcampFeaturedExtractor(final StreamingService streamingService, final ListLinkHandler listLinkHandler,
|
public BandcampFeaturedExtractor(final StreamingService streamingService,
|
||||||
|
final ListLinkHandler listLinkHandler,
|
||||||
final String kioskId) {
|
final String kioskId) {
|
||||||
super(streamingService, listLinkHandler, kioskId);
|
super(streamingService, listLinkHandler, kioskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFetchPage(@Nonnull Downloader downloader) throws IOException, ExtractionException {
|
public void onFetchPage(@Nonnull final Downloader downloader)
|
||||||
|
throws IOException, ExtractionException {
|
||||||
try {
|
try {
|
||||||
json = JsonParser.object().from(
|
json = JsonParser.object().from(
|
||||||
getDownloader().post(
|
getDownloader().post(
|
||||||
|
@ -55,9 +58,8 @@ public class BandcampFeaturedExtractor extends KioskExtractor<PlaylistInfoItem>
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public InfoItemsPage<PlaylistInfoItem> getInitialPage() throws IOException, ExtractionException {
|
public InfoItemsPage<PlaylistInfoItem> getInitialPage()
|
||||||
|
throws IOException, ExtractionException {
|
||||||
|
|
||||||
final JsonArray featuredStories = json.getObject("feed_content")
|
final JsonArray featuredStories = json.getObject("feed_content")
|
||||||
.getObject("stories")
|
.getObject("stories")
|
||||||
.getArray("featured");
|
.getArray("featured");
|
||||||
|
@ -65,8 +67,7 @@ public class BandcampFeaturedExtractor extends KioskExtractor<PlaylistInfoItem>
|
||||||
return extractItems(featuredStories);
|
return extractItems(featuredStories);
|
||||||
}
|
}
|
||||||
|
|
||||||
private InfoItemsPage<PlaylistInfoItem> extractItems(JsonArray featuredStories) {
|
private InfoItemsPage<PlaylistInfoItem> extractItems(final JsonArray featuredStories) {
|
||||||
|
|
||||||
final PlaylistInfoItemsCollector c = new PlaylistInfoItemsCollector(getServiceId());
|
final PlaylistInfoItemsCollector c = new PlaylistInfoItemsCollector(getServiceId());
|
||||||
|
|
||||||
for (int i = 0; i < featuredStories.size(); i++) {
|
for (int i = 0; i < featuredStories.size(); i++) {
|
||||||
|
@ -81,14 +82,13 @@ public class BandcampFeaturedExtractor extends KioskExtractor<PlaylistInfoItem>
|
||||||
}
|
}
|
||||||
|
|
||||||
final JsonObject lastFeaturedStory = featuredStories.getObject(featuredStories.size() - 1);
|
final JsonObject lastFeaturedStory = featuredStories.getObject(featuredStories.size() - 1);
|
||||||
|
|
||||||
return new InfoItemsPage<>(c, getNextPageFrom(lastFeaturedStory));
|
return new InfoItemsPage<>(c, getNextPageFrom(lastFeaturedStory));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Next Page can be generated from metadata of last featured story
|
* Next Page can be generated from metadata of last featured story
|
||||||
*/
|
*/
|
||||||
private Page getNextPageFrom(JsonObject lastFeaturedStory) {
|
private Page getNextPageFrom(final JsonObject lastFeaturedStory) {
|
||||||
final long lastStoryDate = lastFeaturedStory.getLong("story_date");
|
final long lastStoryDate = lastFeaturedStory.getLong("story_date");
|
||||||
final long lastStoryId = lastFeaturedStory.getLong("ntid");
|
final long lastStoryId = lastFeaturedStory.getLong("ntid");
|
||||||
final String lastStoryType = lastFeaturedStory.getString("story_type");
|
final String lastStoryType = lastFeaturedStory.getString("story_type");
|
||||||
|
@ -99,9 +99,10 @@ public class BandcampFeaturedExtractor extends KioskExtractor<PlaylistInfoItem>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InfoItemsPage<PlaylistInfoItem> getPage(Page page) throws IOException, ExtractionException {
|
public InfoItemsPage<PlaylistInfoItem> getPage(final Page page)
|
||||||
|
throws IOException, ExtractionException {
|
||||||
|
|
||||||
JsonObject response;
|
final JsonObject response;
|
||||||
try {
|
try {
|
||||||
response = JsonParser.object().from(
|
response = JsonParser.object().from(
|
||||||
getDownloader().get(page.getUrl()).responseBody()
|
getDownloader().get(page.getUrl()).responseBody()
|
||||||
|
|
|
@ -30,9 +30,9 @@ import static org.schabi.newpipe.extractor.utils.Utils.HTTPS;
|
||||||
public class BandcampPlaylistExtractor extends PlaylistExtractor {
|
public class BandcampPlaylistExtractor extends PlaylistExtractor {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An arbitrarily chosen number above which cover arts won't be fetched individually for each track;
|
* An arbitrarily chosen number above which cover arts won't be fetched individually for each
|
||||||
* instead, it will be assumed that every track has the same cover art as the album, which is not
|
* track; instead, it will be assumed that every track has the same cover art as the album,
|
||||||
* always the case.
|
* which is not always the case.
|
||||||
*/
|
*/
|
||||||
private static final int MAXIMUM_INDIVIDUAL_COVER_ARTS = 10;
|
private static final int MAXIMUM_INDIVIDUAL_COVER_ARTS = 10;
|
||||||
|
|
||||||
|
@ -41,12 +41,14 @@ public class BandcampPlaylistExtractor extends PlaylistExtractor {
|
||||||
private JsonArray trackInfo;
|
private JsonArray trackInfo;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
public BandcampPlaylistExtractor(final StreamingService service, final ListLinkHandler linkHandler) {
|
public BandcampPlaylistExtractor(final StreamingService service,
|
||||||
|
final ListLinkHandler linkHandler) {
|
||||||
super(service, linkHandler);
|
super(service, linkHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException {
|
public void onFetchPage(@Nonnull final Downloader downloader)
|
||||||
|
throws IOException, ExtractionException {
|
||||||
final String html = downloader.get(getLinkHandler().getUrl()).responseBody();
|
final String html = downloader.get(getLinkHandler().getUrl()).responseBody();
|
||||||
document = Jsoup.parse(html);
|
document = Jsoup.parse(html);
|
||||||
albumJson = getAlbumInfoJson(html);
|
albumJson = getAlbumInfoJson(html);
|
||||||
|
@ -115,7 +117,7 @@ public class BandcampPlaylistExtractor extends PlaylistExtractor {
|
||||||
final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
|
final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
|
||||||
|
|
||||||
for (int i = 0; i < trackInfo.size(); i++) {
|
for (int i = 0; i < trackInfo.size(); i++) {
|
||||||
JsonObject track = trackInfo.getObject(i);
|
final JsonObject track = trackInfo.getObject(i);
|
||||||
|
|
||||||
if (trackInfo.size() < MAXIMUM_INDIVIDUAL_COVER_ARTS) {
|
if (trackInfo.size() < MAXIMUM_INDIVIDUAL_COVER_ARTS) {
|
||||||
// Load cover art of every track individually
|
// Load cover art of every track individually
|
||||||
|
|
|
@ -6,9 +6,10 @@ import org.schabi.newpipe.extractor.playlist.PlaylistInfoItemExtractor;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class BandcampPlaylistInfoItemExtractor implements PlaylistInfoItemExtractor {
|
public class BandcampPlaylistInfoItemExtractor implements PlaylistInfoItemExtractor {
|
||||||
private final Element searchResult, resultInfo;
|
private final Element searchResult;
|
||||||
|
private final Element resultInfo;
|
||||||
|
|
||||||
public BandcampPlaylistInfoItemExtractor(@Nonnull Element searchResult) {
|
public BandcampPlaylistInfoItemExtractor(@Nonnull final Element searchResult) {
|
||||||
this.searchResult = searchResult;
|
this.searchResult = searchResult;
|
||||||
resultInfo = searchResult.getElementsByClass("result-info").first();
|
resultInfo = searchResult.getElementsByClass("result-info").first();
|
||||||
}
|
}
|
||||||
|
@ -41,6 +42,8 @@ public class BandcampPlaylistInfoItemExtractor implements PlaylistInfoItemExtrac
|
||||||
.getElementsByTag("img").first();
|
.getElementsByTag("img").first();
|
||||||
if (img != null) {
|
if (img != null) {
|
||||||
return img.attr("src");
|
return img.attr("src");
|
||||||
} else return null;
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,13 +28,15 @@ public class BandcampRadioExtractor extends KioskExtractor<StreamInfoItem> {
|
||||||
|
|
||||||
private JsonObject json = null;
|
private JsonObject json = null;
|
||||||
|
|
||||||
public BandcampRadioExtractor(final StreamingService streamingService, final ListLinkHandler linkHandler,
|
public BandcampRadioExtractor(final StreamingService streamingService,
|
||||||
|
final ListLinkHandler linkHandler,
|
||||||
final String kioskId) {
|
final String kioskId) {
|
||||||
super(streamingService, linkHandler, kioskId);
|
super(streamingService, linkHandler, kioskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException {
|
public void onFetchPage(@Nonnull final Downloader downloader)
|
||||||
|
throws IOException, ExtractionException {
|
||||||
try {
|
try {
|
||||||
json = JsonParser.object().from(
|
json = JsonParser.object().from(
|
||||||
getDownloader().get(RADIO_API_URL).responseBody());
|
getDownloader().get(RADIO_API_URL).responseBody());
|
||||||
|
|
|
@ -23,10 +23,9 @@ public class BandcampRadioInfoItemExtractor implements StreamInfoItemExtractor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getDuration() {
|
public long getDuration() {
|
||||||
/* Duration is only present in the more detailed information that has to be queried separately.
|
/* Duration is only present in the more detailed information that has to be queried
|
||||||
* Therefore, over 300 queries would be needed every time the kiosk is opened if we were to
|
separately. Therefore, over 300 queries would be needed every time the kiosk is opened if we
|
||||||
* display the real value.
|
were to display the real value. */
|
||||||
*/
|
|
||||||
//return query(show.getInt("id")).getLong("audio_duration");
|
//return query(show.getInt("id")).getLong("audio_duration");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,28 +26,31 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper.*;
|
import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper.BASE_API_URL;
|
||||||
|
import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper.BASE_URL;
|
||||||
|
import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper.getImageUrl;
|
||||||
|
|
||||||
public class BandcampRadioStreamExtractor extends BandcampStreamExtractor {
|
public class BandcampRadioStreamExtractor extends BandcampStreamExtractor {
|
||||||
|
|
||||||
private JsonObject showInfo;
|
private JsonObject showInfo;
|
||||||
|
|
||||||
public BandcampRadioStreamExtractor(final StreamingService service, final LinkHandler linkHandler) {
|
public BandcampRadioStreamExtractor(final StreamingService service,
|
||||||
|
final LinkHandler linkHandler) {
|
||||||
super(service, linkHandler);
|
super(service, linkHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JsonObject query(final int id) throws ParsingException {
|
static JsonObject query(final int id) throws ParsingException {
|
||||||
try {
|
try {
|
||||||
return JsonParser.object().from(
|
return JsonParser.object().from(NewPipe.getDownloader()
|
||||||
NewPipe.getDownloader().get(BASE_API_URL + "/bcweekly/1/get?id=" + id).responseBody()
|
.get(BASE_API_URL + "/bcweekly/1/get?id=" + id).responseBody());
|
||||||
);
|
|
||||||
} catch (final IOException | ReCaptchaException | JsonParserException e) {
|
} catch (final IOException | ReCaptchaException | JsonParserException e) {
|
||||||
throw new ParsingException("could not get show data", e);
|
throw new ParsingException("could not get show data", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException {
|
public void onFetchPage(@Nonnull final Downloader downloader)
|
||||||
|
throws IOException, ExtractionException {
|
||||||
showInfo = query(Integer.parseInt(getId()));
|
showInfo = query(Integer.parseInt(getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ import javax.annotation.Nonnull;
|
||||||
public class BandcampRelatedPlaylistInfoItemExtractor implements PlaylistInfoItemExtractor {
|
public class BandcampRelatedPlaylistInfoItemExtractor implements PlaylistInfoItemExtractor {
|
||||||
private final Element relatedAlbum;
|
private final Element relatedAlbum;
|
||||||
|
|
||||||
public BandcampRelatedPlaylistInfoItemExtractor(@Nonnull Element relatedAlbum) {
|
public BandcampRelatedPlaylistInfoItemExtractor(@Nonnull final Element relatedAlbum) {
|
||||||
this.relatedAlbum = relatedAlbum;
|
this.relatedAlbum = relatedAlbum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,8 @@ import java.util.List;
|
||||||
|
|
||||||
public class BandcampSearchExtractor extends SearchExtractor {
|
public class BandcampSearchExtractor extends SearchExtractor {
|
||||||
|
|
||||||
public BandcampSearchExtractor(StreamingService service, SearchQueryHandler linkHandler) {
|
public BandcampSearchExtractor(final StreamingService service,
|
||||||
|
final SearchQueryHandler linkHandler) {
|
||||||
super(service, linkHandler);
|
super(service, linkHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +48,8 @@ public class BandcampSearchExtractor extends SearchExtractor {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public InfoItemsPage<InfoItem> getPage(final Page page) throws IOException, ExtractionException {
|
public InfoItemsPage<InfoItem> getPage(final Page page)
|
||||||
|
throws IOException, ExtractionException {
|
||||||
final String html = getDownloader().get(page.getUrl()).responseBody();
|
final String html = getDownloader().get(page.getUrl()).responseBody();
|
||||||
|
|
||||||
final MultiInfoItemsCollector collector = new MultiInfoItemsCollector(getServiceId());
|
final MultiInfoItemsCollector collector = new MultiInfoItemsCollector(getServiceId());
|
||||||
|
@ -86,8 +88,9 @@ public class BandcampSearchExtractor extends SearchExtractor {
|
||||||
|
|
||||||
// Count pages
|
// Count pages
|
||||||
final Elements pageLists = d.getElementsByClass("pagelist");
|
final Elements pageLists = d.getElementsByClass("pagelist");
|
||||||
if (pageLists.isEmpty())
|
if (pageLists.isEmpty()) {
|
||||||
return new InfoItemsPage<>(collector, null);
|
return new InfoItemsPage<>(collector, null);
|
||||||
|
}
|
||||||
|
|
||||||
final Elements pages = pageLists.first().getElementsByTag("li");
|
final Elements pages = pageLists.first().getElementsByTag("li");
|
||||||
|
|
||||||
|
@ -120,7 +123,7 @@ public class BandcampSearchExtractor extends SearchExtractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException {
|
public void onFetchPage(@Nonnull final Downloader downloader)
|
||||||
|
throws IOException, ExtractionException {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
|
|
||||||
package org.schabi.newpipe.extractor.services.bandcamp.extractors;
|
package org.schabi.newpipe.extractor.services.bandcamp.extractors;
|
||||||
|
|
||||||
|
import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper.getImageUrl;
|
||||||
|
|
||||||
import com.grack.nanojson.JsonObject;
|
import com.grack.nanojson.JsonObject;
|
||||||
import com.grack.nanojson.JsonParserException;
|
import com.grack.nanojson.JsonParserException;
|
||||||
|
|
||||||
import org.jsoup.Jsoup;
|
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.MediaFormat;
|
import org.schabi.newpipe.extractor.MediaFormat;
|
||||||
import org.schabi.newpipe.extractor.MetaInfo;
|
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
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;
|
||||||
|
@ -17,19 +19,21 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
|
import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
|
||||||
import org.schabi.newpipe.extractor.localization.DateWrapper;
|
import org.schabi.newpipe.extractor.localization.DateWrapper;
|
||||||
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItemsCollector;
|
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItemsCollector;
|
||||||
import org.schabi.newpipe.extractor.stream.*;
|
import org.schabi.newpipe.extractor.stream.AudioStream;
|
||||||
|
import org.schabi.newpipe.extractor.stream.Description;
|
||||||
|
import org.schabi.newpipe.extractor.stream.StreamExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.stream.StreamType;
|
||||||
|
import org.schabi.newpipe.extractor.stream.VideoStream;
|
||||||
import org.schabi.newpipe.extractor.utils.JsonUtils;
|
import org.schabi.newpipe.extractor.utils.JsonUtils;
|
||||||
import org.schabi.newpipe.extractor.utils.Utils;
|
import org.schabi.newpipe.extractor.utils.Utils;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper.getImageUrl;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class BandcampStreamExtractor extends StreamExtractor {
|
public class BandcampStreamExtractor extends StreamExtractor {
|
||||||
|
|
||||||
|
@ -43,7 +47,8 @@ public class BandcampStreamExtractor extends StreamExtractor {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException {
|
public void onFetchPage(@Nonnull final Downloader downloader)
|
||||||
|
throws IOException, ExtractionException {
|
||||||
final String html = downloader.get(getLinkHandler().getUrl()).responseBody();
|
final String html = downloader.get(getLinkHandler().getUrl()).responseBody();
|
||||||
document = Jsoup.parse(html);
|
document = Jsoup.parse(html);
|
||||||
albumJson = getAlbumInfoJson(html);
|
albumJson = getAlbumInfoJson(html);
|
||||||
|
@ -94,7 +99,7 @@ public class BandcampStreamExtractor extends StreamExtractor {
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getUploaderName() {
|
public String getUploaderName() throws ParsingException {
|
||||||
return albumJson.getString("artist");
|
return albumJson.getString("artist");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,8 +118,11 @@ public class BandcampStreamExtractor extends StreamExtractor {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getThumbnailUrl() throws ParsingException {
|
public String getThumbnailUrl() throws ParsingException {
|
||||||
if (albumJson.isNull("art_id")) return "";
|
if (albumJson.isNull("art_id")) {
|
||||||
else return getImageUrl(albumJson.getLong("art_id"), true);
|
return "";
|
||||||
|
} else {
|
||||||
|
return getImageUrl(albumJson.getLong("art_id"), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
@ -170,15 +178,12 @@ public class BandcampStreamExtractor extends StreamExtractor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlaylistInfoItemsCollector getRelatedItems() {
|
public PlaylistInfoItemsCollector getRelatedItems() {
|
||||||
|
final PlaylistInfoItemsCollector collector = new PlaylistInfoItemsCollector(getServiceId());
|
||||||
|
final Elements recommendedAlbums = document.getElementsByClass("recommended-album");
|
||||||
|
|
||||||
PlaylistInfoItemsCollector collector = new PlaylistInfoItemsCollector(getServiceId());
|
for (final Element album : recommendedAlbums) {
|
||||||
|
|
||||||
Elements recommendedAlbums = document.getElementsByClass("recommended-album");
|
|
||||||
|
|
||||||
for (Element album : recommendedAlbums) {
|
|
||||||
collector.commit(new BandcampRelatedPlaylistInfoItemExtractor(album));
|
collector.commit(new BandcampRelatedPlaylistInfoItemExtractor(album));
|
||||||
}
|
}
|
||||||
|
|
||||||
return collector;
|
return collector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,22 +191,21 @@ public class BandcampStreamExtractor extends StreamExtractor {
|
||||||
@Override
|
@Override
|
||||||
public String getCategory() {
|
public String getCategory() {
|
||||||
// Get first tag from html, which is the artist's Genre
|
// Get first tag from html, which is the artist's Genre
|
||||||
return document
|
return document.getElementsByClass("tralbum-tags").stream()
|
||||||
.getElementsByClass("tralbum-tags").first()
|
.flatMap(element -> element.getElementsByClass("tag").stream())
|
||||||
.getElementsByClass("tag").first().text();
|
.map(Element::text)
|
||||||
|
.findFirst()
|
||||||
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getLicence() {
|
public String getLicence() {
|
||||||
|
/* Tests resulted in this mapping of ints to licence:
|
||||||
|
https://cloud.disroot.org/s/ZTWBxbQ9fKRmRWJ/preview (screenshot from a Bandcamp artist's
|
||||||
|
account) */
|
||||||
|
|
||||||
int license = current.getInt("license_type");
|
switch (current.getInt("license_type")) {
|
||||||
|
|
||||||
/* Tests resulted in this mapping of ints to licence: https://cloud.disroot.org/s/ZTWBxbQ9fKRmRWJ/preview
|
|
||||||
* (screenshot from a Bandcamp artist's account)
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (license) {
|
|
||||||
case 1:
|
case 1:
|
||||||
return "All rights reserved ©";
|
return "All rights reserved ©";
|
||||||
case 2:
|
case 2:
|
||||||
|
|
|
@ -2,10 +2,13 @@
|
||||||
|
|
||||||
package org.schabi.newpipe.extractor.services.bandcamp.extractors;
|
package org.schabi.newpipe.extractor.services.bandcamp.extractors;
|
||||||
|
|
||||||
|
import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper.BASE_API_URL;
|
||||||
|
|
||||||
import com.grack.nanojson.JsonArray;
|
import com.grack.nanojson.JsonArray;
|
||||||
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.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
import org.schabi.newpipe.extractor.downloader.Downloader;
|
import org.schabi.newpipe.extractor.downloader.Downloader;
|
||||||
|
@ -18,8 +21,6 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper.BASE_API_URL;
|
|
||||||
|
|
||||||
public class BandcampSuggestionExtractor extends SuggestionExtractor {
|
public class BandcampSuggestionExtractor extends SuggestionExtractor {
|
||||||
|
|
||||||
private static final String AUTOCOMPLETE_URL = BASE_API_URL + "/fuzzysearch/1/autocomplete?q=";
|
private static final String AUTOCOMPLETE_URL = BASE_API_URL + "/fuzzysearch/1/autocomplete?q=";
|
||||||
|
@ -32,9 +33,8 @@ public class BandcampSuggestionExtractor extends SuggestionExtractor {
|
||||||
final Downloader downloader = NewPipe.getDownloader();
|
final Downloader downloader = NewPipe.getDownloader();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final JsonObject fuzzyResults = JsonParser.object().from(
|
final JsonObject fuzzyResults = JsonParser.object().from(downloader
|
||||||
downloader.get(AUTOCOMPLETE_URL + URLEncoder.encode(query, "UTF-8")).responseBody()
|
.get(AUTOCOMPLETE_URL + URLEncoder.encode(query, "UTF-8")).responseBody());
|
||||||
);
|
|
||||||
|
|
||||||
final JsonArray jsonArray = fuzzyResults.getObject("auto")
|
final JsonArray jsonArray = fuzzyResults.getObject("auto")
|
||||||
.getArray("results");
|
.getArray("results");
|
||||||
|
@ -44,7 +44,9 @@ public class BandcampSuggestionExtractor extends SuggestionExtractor {
|
||||||
for (final Object fuzzyResult : jsonArray) {
|
for (final Object fuzzyResult : jsonArray) {
|
||||||
final String res = ((JsonObject) fuzzyResult).getString("name");
|
final String res = ((JsonObject) fuzzyResult).getString("name");
|
||||||
|
|
||||||
if (!suggestions.contains(res)) suggestions.add(res);
|
if (!suggestions.contains(res)) {
|
||||||
|
suggestions.add(res);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return suggestions;
|
return suggestions;
|
||||||
|
|
|
@ -9,9 +9,9 @@ import javax.annotation.Nullable;
|
||||||
public class BandcampDiscographStreamInfoItemExtractor extends BandcampStreamInfoItemExtractor {
|
public class BandcampDiscographStreamInfoItemExtractor extends BandcampStreamInfoItemExtractor {
|
||||||
|
|
||||||
private final JsonObject discograph;
|
private final JsonObject discograph;
|
||||||
public BandcampDiscographStreamInfoItemExtractor(final JsonObject discograph, final String uploaderUrl) {
|
public BandcampDiscographStreamInfoItemExtractor(final JsonObject discograph,
|
||||||
|
final String uploaderUrl) {
|
||||||
super(uploaderUrl);
|
super(uploaderUrl);
|
||||||
|
|
||||||
this.discograph = discograph;
|
this.discograph = discograph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,14 +18,16 @@ public class BandcampPlaylistStreamInfoItemExtractor extends BandcampStreamInfoI
|
||||||
private String substituteCoverUrl;
|
private String substituteCoverUrl;
|
||||||
private final StreamingService service;
|
private final StreamingService service;
|
||||||
|
|
||||||
public BandcampPlaylistStreamInfoItemExtractor(final JsonObject track, final String uploaderUrl,
|
public BandcampPlaylistStreamInfoItemExtractor(final JsonObject track,
|
||||||
|
final String uploaderUrl,
|
||||||
final StreamingService service) {
|
final StreamingService service) {
|
||||||
super(uploaderUrl);
|
super(uploaderUrl);
|
||||||
this.track = track;
|
this.track = track;
|
||||||
this.service = service;
|
this.service = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BandcampPlaylistStreamInfoItemExtractor(final JsonObject track, final String uploaderUrl,
|
public BandcampPlaylistStreamInfoItemExtractor(final JsonObject track,
|
||||||
|
final String uploaderUrl,
|
||||||
final String substituteCoverUrl) {
|
final String substituteCoverUrl) {
|
||||||
this(track, uploaderUrl, (StreamingService) null);
|
this(track, uploaderUrl, (StreamingService) null);
|
||||||
this.substituteCoverUrl = substituteCoverUrl;
|
this.substituteCoverUrl = substituteCoverUrl;
|
||||||
|
|
|
@ -7,9 +7,11 @@ import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class BandcampSearchStreamInfoItemExtractor extends BandcampStreamInfoItemExtractor {
|
public class BandcampSearchStreamInfoItemExtractor extends BandcampStreamInfoItemExtractor {
|
||||||
|
|
||||||
private final Element resultInfo, searchResult;
|
private final Element resultInfo;
|
||||||
|
private final Element searchResult;
|
||||||
|
|
||||||
public BandcampSearchStreamInfoItemExtractor(final Element searchResult, final String uploaderUrl) {
|
public BandcampSearchStreamInfoItemExtractor(final Element searchResult,
|
||||||
|
final String uploaderUrl) {
|
||||||
super(uploaderUrl);
|
super(uploaderUrl);
|
||||||
this.searchResult = searchResult;
|
this.searchResult = searchResult;
|
||||||
resultInfo = searchResult.getElementsByClass("result-info").first();
|
resultInfo = searchResult.getElementsByClass("result-info").first();
|
||||||
|
|
|
@ -30,7 +30,8 @@ public class BandcampChannelLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||||
|
|
||||||
return String.valueOf(bandData.getLong("id"));
|
return String.valueOf(bandData.getLong("id"));
|
||||||
|
|
||||||
} catch (final IOException | ReCaptchaException | ArrayIndexOutOfBoundsException | JsonParserException e) {
|
} catch (final IOException | ReCaptchaException | ArrayIndexOutOfBoundsException
|
||||||
|
| JsonParserException e) {
|
||||||
throw new ParsingException("Download failed", e);
|
throw new ParsingException("Download failed", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +47,8 @@ public class BandcampChannelLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||||
.getString("bandcamp_url")
|
.getString("bandcamp_url")
|
||||||
.replace("http://", "https://");
|
.replace("http://", "https://");
|
||||||
} catch (final NullPointerException e) {
|
} catch (final NullPointerException e) {
|
||||||
throw new ParsingException("JSON does not contain URL (invalid id?) or is otherwise invalid", e);
|
throw new ParsingException(
|
||||||
|
"JSON does not contain URL (invalid id?) or is otherwise invalid", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -55,16 +57,18 @@ public class BandcampChannelLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||||
* Accepts only pages that lead to the root of an artist profile. Supports external pages.
|
* Accepts only pages that lead to the root of an artist profile. Supports external pages.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onAcceptUrl(String url) throws ParsingException {
|
public boolean onAcceptUrl(final String url) throws ParsingException {
|
||||||
|
|
||||||
url = url.toLowerCase();
|
final String lowercaseUrl = url.toLowerCase();
|
||||||
|
|
||||||
// https: | | artist.bandcamp.com | releases
|
// https: | | artist.bandcamp.com | releases
|
||||||
// 0 1 2 3
|
// 0 1 2 3
|
||||||
String[] splitUrl = url.split("/");
|
final String[] splitUrl = lowercaseUrl.split("/");
|
||||||
|
|
||||||
// URL is too short
|
// URL is too short
|
||||||
if (splitUrl.length < 3) return false;
|
if (splitUrl.length < 3) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Must have "releases" or "music" as segment after url or none at all
|
// Must have "releases" or "music" as segment after url or none at all
|
||||||
if (splitUrl.length > 3 && !(
|
if (splitUrl.length > 3 && !(
|
||||||
|
@ -80,7 +84,7 @@ public class BandcampChannelLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test whether domain is supported
|
// Test whether domain is supported
|
||||||
return BandcampExtractorHelper.isSupportedDomain(url);
|
return BandcampExtractorHelper.isSupportedDomain(lowercaseUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,21 +13,25 @@ import java.util.List;
|
||||||
public class BandcampCommentsLinkHandlerFactory extends ListLinkHandlerFactory {
|
public class BandcampCommentsLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId(String url) throws ParsingException {
|
public String getId(final String url) throws ParsingException {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onAcceptUrl(String url) throws ParsingException {
|
public boolean onAcceptUrl(final String url) throws ParsingException {
|
||||||
// Don't accept URLs that don't point to a track
|
// Don't accept URLs that don't point to a track
|
||||||
if (!url.toLowerCase().matches("https?://.+\\..+/(track|album)/.+")) return false;
|
if (!url.toLowerCase().matches("https?://.+\\..+/(track|album)/.+")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Test whether domain is supported
|
// Test whether domain is supported
|
||||||
return BandcampExtractorHelper.isSupportedDomain(url);
|
return BandcampExtractorHelper.isSupportedDomain(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUrl(String id, List<String> contentFilter, String sortFilter) throws ParsingException {
|
public String getUrl(final String id,
|
||||||
|
final List<String> contentFilter,
|
||||||
|
final String sortFilter) throws ParsingException {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,9 @@ import static org.schabi.newpipe.extractor.services.bandcamp.extractors.Bandcamp
|
||||||
public class BandcampFeaturedLinkHandlerFactory extends ListLinkHandlerFactory {
|
public class BandcampFeaturedLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUrl(final String id, final List<String> contentFilter, final String sortFilter) {
|
public String getUrl(final String id,
|
||||||
|
final List<String> contentFilter,
|
||||||
|
final String sortFilter) {
|
||||||
if (id.equals(KIOSK_FEATURED)) {
|
if (id.equals(KIOSK_FEATURED)) {
|
||||||
return FEATURED_API_URL; // doesn't have a website
|
return FEATURED_API_URL; // doesn't have a website
|
||||||
} else if (id.equals(KIOSK_RADIO)) {
|
} else if (id.equals(KIOSK_RADIO)) {
|
||||||
|
@ -27,11 +29,11 @@ public class BandcampFeaturedLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId(String url) {
|
public String getId(final String url) {
|
||||||
url = Utils.replaceHttpWithHttps(url);
|
final String fixedUrl = Utils.replaceHttpWithHttps(url);
|
||||||
if (BandcampExtractorHelper.isRadioUrl(url) || url.equals(RADIO_API_URL)) {
|
if (BandcampExtractorHelper.isRadioUrl(fixedUrl) || fixedUrl.equals(RADIO_API_URL)) {
|
||||||
return KIOSK_RADIO;
|
return KIOSK_RADIO;
|
||||||
} else if (url.equals(FEATURED_API_URL)) {
|
} else if (fixedUrl.equals(FEATURED_API_URL)) {
|
||||||
return KIOSK_FEATURED;
|
return KIOSK_FEATURED;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -39,8 +41,10 @@ public class BandcampFeaturedLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onAcceptUrl(String url) {
|
public boolean onAcceptUrl(final String url) {
|
||||||
url = Utils.replaceHttpWithHttps(url);
|
final String fixedUrl = Utils.replaceHttpWithHttps(url);
|
||||||
return url.equals(FEATURED_API_URL) || (url.equals(RADIO_API_URL) || BandcampExtractorHelper.isRadioUrl(url));
|
return fixedUrl.equals(FEATURED_API_URL)
|
||||||
|
|| fixedUrl.equals(RADIO_API_URL)
|
||||||
|
|| BandcampExtractorHelper.isRadioUrl(fixedUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,9 @@ public class BandcampPlaylistLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUrl(final String url, final List<String> contentFilter, final String sortFilter)
|
public String getUrl(final String url,
|
||||||
throws ParsingException {
|
final List<String> contentFilter,
|
||||||
|
final String sortFilter) throws ParsingException {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +31,9 @@ public class BandcampPlaylistLinkHandlerFactory extends ListLinkHandlerFactory {
|
||||||
public boolean onAcceptUrl(final String url) throws ParsingException {
|
public boolean onAcceptUrl(final String url) throws ParsingException {
|
||||||
|
|
||||||
// Exclude URLs which do not lead to an album
|
// Exclude URLs which do not lead to an album
|
||||||
if (!url.toLowerCase().matches("https?://.+\\..+/album/.+")) return false;
|
if (!url.toLowerCase().matches("https?://.+\\..+/album/.+")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Test whether domain is supported
|
// Test whether domain is supported
|
||||||
return BandcampExtractorHelper.isSupportedDomain(url);
|
return BandcampExtractorHelper.isSupportedDomain(url);
|
||||||
|
|
|
@ -15,14 +15,11 @@ public class BandcampSearchQueryHandlerFactory extends SearchQueryHandlerFactory
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUrl(final String query, final List<String> contentFilter, final String sortFilter)
|
public String getUrl(final String query,
|
||||||
throws ParsingException {
|
final List<String> contentFilter,
|
||||||
|
final String sortFilter) throws ParsingException {
|
||||||
try {
|
try {
|
||||||
|
return BASE_URL + "/search?q=" + URLEncoder.encode(query, "UTF-8") + "&page=1";
|
||||||
return BASE_URL + "/search?q=" +
|
|
||||||
URLEncoder.encode(query, "UTF-8")
|
|
||||||
+ "&page=1";
|
|
||||||
|
|
||||||
} catch (final UnsupportedEncodingException e) {
|
} catch (final UnsupportedEncodingException e) {
|
||||||
throw new ParsingException("query \"" + query + "\" could not be encoded", e);
|
throw new ParsingException("query \"" + query + "\" could not be encoded", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,10 +50,14 @@ public class BandcampStreamLinkHandlerFactory extends LinkHandlerFactory {
|
||||||
public boolean onAcceptUrl(final String url) throws ParsingException {
|
public boolean onAcceptUrl(final String url) throws ParsingException {
|
||||||
|
|
||||||
// Accept Bandcamp radio
|
// Accept Bandcamp radio
|
||||||
if (BandcampExtractorHelper.isRadioUrl(url)) return true;
|
if (BandcampExtractorHelper.isRadioUrl(url)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Don't accept URLs that don't point to a track
|
// Don't accept URLs that don't point to a track
|
||||||
if (!url.toLowerCase().matches("https?://.+\\..+/track/.+")) return false;
|
if (!url.toLowerCase().matches("https?://.+\\..+/track/.+")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Test whether domain is supported
|
// Test whether domain is supported
|
||||||
return BandcampExtractorHelper.isSupportedDomain(url);
|
return BandcampExtractorHelper.isSupportedDomain(url);
|
||||||
|
|
Loading…
Reference in New Issue