NewPipeExtractor/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampPlaylistExtractor.java

146 lines
5.2 KiB
Java
Raw Normal View History

2019-12-22 02:55:54 +01:00
package org.schabi.newpipe.extractor.services.bandcamp.extractors;
2022-03-17 17:13:25 +01:00
import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper.getImageUrl;
import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampStreamExtractor.getAlbumInfoJson;
import static org.schabi.newpipe.extractor.utils.JsonUtils.getJsonData;
import static org.schabi.newpipe.extractor.utils.Utils.EMPTY_STRING;
import static org.schabi.newpipe.extractor.utils.Utils.HTTPS;
import com.grack.nanojson.JsonArray;
import com.grack.nanojson.JsonObject;
import com.grack.nanojson.JsonParserException;
2022-03-17 17:13:25 +01:00
2019-12-22 02:55:54 +01:00
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
2020-08-02 16:23:53 +02:00
import org.schabi.newpipe.extractor.Page;
2019-12-22 02:55:54 +01:00
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
2019-12-22 02:55:54 +01:00
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.playlist.PlaylistExtractor;
import org.schabi.newpipe.extractor.services.bandcamp.extractors.streaminfoitem.BandcampPlaylistStreamInfoItemExtractor;
2019-12-22 02:55:54 +01:00
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
import java.io.IOException;
2022-03-17 17:13:25 +01:00
import javax.annotation.Nonnull;
2019-12-22 02:55:54 +01:00
public class BandcampPlaylistExtractor extends PlaylistExtractor {
/**
2022-03-18 17:50:25 +01:00
* An arbitrarily chosen number above which cover arts won't be fetched individually for each
* track; instead, it will be assumed that every track has the same cover art as the album,
* which is not always the case.
*/
private static final int MAXIMUM_INDIVIDUAL_COVER_ARTS = 10;
2019-12-22 02:55:54 +01:00
private Document document;
private JsonObject albumJson;
private JsonArray trackInfo;
2019-12-22 02:55:54 +01:00
private String name;
2022-03-18 17:50:25 +01:00
public BandcampPlaylistExtractor(final StreamingService service,
final ListLinkHandler linkHandler) {
2019-12-22 02:55:54 +01:00
super(service, linkHandler);
}
@Override
2022-03-18 17:50:25 +01:00
public void onFetchPage(@Nonnull final Downloader downloader)
throws IOException, ExtractionException {
final String html = downloader.get(getLinkHandler().getUrl()).responseBody();
2019-12-22 02:55:54 +01:00
document = Jsoup.parse(html);
albumJson = getAlbumInfoJson(html);
trackInfo = albumJson.getArray("trackinfo");
2019-12-22 02:55:54 +01:00
try {
2020-10-08 17:56:03 +02:00
name = getJsonData(html, "data-embed").getString("album_title");
} catch (final JsonParserException e) {
2019-12-22 02:55:54 +01:00
throw new ParsingException("Faulty JSON; page likely does not contain album data", e);
} catch (final ArrayIndexOutOfBoundsException e) {
2019-12-22 02:55:54 +01:00
throw new ParsingException("JSON does not exist", e);
}
if (trackInfo.isEmpty()) {
// Albums without trackInfo need to be purchased before they can be played
throw new ContentNotAvailableException("Album needs to be purchased");
2019-12-22 02:55:54 +01:00
}
}
@Nonnull
2019-12-22 02:55:54 +01:00
@Override
public String getThumbnailUrl() throws ParsingException {
if (albumJson.isNull("art_id")) {
return EMPTY_STRING;
} else {
return getImageUrl(albumJson.getLong("art_id"), true);
}
2019-12-22 02:55:54 +01:00
}
@Override
public String getUploaderUrl() throws ParsingException {
final String[] parts = getUrl().split("/");
2019-12-22 02:55:54 +01:00
// https: (/) (/) * .bandcamp.com (/) and leave out the rest
return HTTPS + parts[2] + "/";
2019-12-22 02:55:54 +01:00
}
@Override
public String getUploaderName() {
return albumJson.getString("artist");
}
@Override
public String getUploaderAvatarUrl() {
2022-03-17 17:13:25 +01:00
return document.getElementsByClass("band-photo").stream()
.map(element -> element.attr("src"))
.findFirst()
.orElse(EMPTY_STRING);
2019-12-22 02:55:54 +01:00
}
2021-02-19 15:51:02 +01:00
@Override
public boolean isUploaderVerified() throws ParsingException {
return false;
}
2019-12-22 02:55:54 +01:00
@Override
public long getStreamCount() {
return trackInfo.size();
2019-12-22 02:55:54 +01:00
}
@Nonnull
@Override
public InfoItemsPage<StreamInfoItem> getInitialPage() throws ExtractionException {
final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
2019-12-22 02:55:54 +01:00
for (int i = 0; i < trackInfo.size(); i++) {
2022-03-18 17:50:25 +01:00
final JsonObject track = trackInfo.getObject(i);
2019-12-22 02:55:54 +01:00
if (trackInfo.size() < MAXIMUM_INDIVIDUAL_COVER_ARTS) {
// Load cover art of every track individually
collector.commit(new BandcampPlaylistStreamInfoItemExtractor(
track, getUploaderUrl(), getService()));
} else {
// Pretend every track has the same cover art as the album
collector.commit(new BandcampPlaylistStreamInfoItemExtractor(
track, getUploaderUrl(), getThumbnailUrl()));
}
2019-12-22 02:55:54 +01:00
}
return new InfoItemsPage<>(collector, null);
}
@Override
public InfoItemsPage<StreamInfoItem> getPage(final Page page) {
2019-12-22 02:55:54 +01:00
return null;
}
2020-08-02 16:23:53 +02:00
@Nonnull
2019-12-22 02:55:54 +01:00
@Override
2020-08-02 16:23:53 +02:00
public String getName() throws ParsingException {
return name;
2019-12-22 02:55:54 +01:00
}
}