diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampChannelExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampChannelExtractor.java index e4e2c2b57..80e7ba27e 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampChannelExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampChannelExtractor.java @@ -2,6 +2,8 @@ package org.schabi.newpipe.extractor.services.bandcamp.extractors; +import static org.schabi.newpipe.extractor.utils.Utils.replaceHttpWithHttps; + import com.grack.nanojson.JsonArray; import com.grack.nanojson.JsonObject; @@ -19,6 +21,8 @@ import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; import java.io.IOException; +import java.util.Objects; +import java.util.stream.Stream; import javax.annotation.Nonnull; @@ -48,21 +52,18 @@ public class BandcampChannelExtractor extends ChannelExtractor { */ try { final String html = getDownloader() - .get(channelInfo.getString("bandcamp_url") - .replace("http://", "https://")) + .get(replaceHttpWithHttps(channelInfo.getString("bandcamp_url"))) .responseBody(); - return Jsoup.parse(html) - .getElementById("customHeader") - .getElementsByTag("img") - .first() - .attr("src"); + return Stream.of(Jsoup.parse(html).getElementById("customHeader")) + .filter(Objects::nonNull) + .flatMap(element -> element.getElementsByTag("img").stream()) + .map(element -> element.attr("src")) + .findFirst() + .orElse(""); // no banner available } catch (final IOException | ReCaptchaException e) { throw new ParsingException("Could not download artist web site", e); - } catch (final NullPointerException e) { - // No banner available - return ""; } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampChannelInfoItemExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampChannelInfoItemExtractor.java index 405824af7..f89a63405 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampChannelInfoItemExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampChannelInfoItemExtractor.java @@ -28,13 +28,7 @@ public class BandcampChannelInfoItemExtractor implements ChannelInfoItemExtracto @Override public String getThumbnailUrl() throws ParsingException { - final Element img = searchResult.getElementsByClass("art").first() - .getElementsByTag("img").first(); - if (img != null) { - return img.attr("src"); - } else { - return null; - } + return BandcampExtractorHelper.getThumbnailUrlFromSearchResult(searchResult); } @Override diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampCommentsInfoItemExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampCommentsInfoItemExtractor.java index a3ca0d7df..661f624e9 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampCommentsInfoItemExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampCommentsInfoItemExtractor.java @@ -4,6 +4,8 @@ import org.jsoup.nodes.Element; import org.schabi.newpipe.extractor.comments.CommentsInfoItemExtractor; import org.schabi.newpipe.extractor.exceptions.ParsingException; +import java.util.Objects; + public class BandcampCommentsInfoItemExtractor implements CommentsInfoItemExtractor { private final Element writing; @@ -16,7 +18,7 @@ public class BandcampCommentsInfoItemExtractor implements CommentsInfoItemExtrac @Override public String getName() throws ParsingException { - return writing.getElementsByClass("text").first().ownText(); + return getCommentText(); } @Override @@ -30,13 +32,21 @@ public class BandcampCommentsInfoItemExtractor implements CommentsInfoItemExtrac } @Override - public String getCommentText() { - return writing.getElementsByClass("text").first().ownText(); + public String getCommentText() throws ParsingException { + return writing.getElementsByClass("text").stream() + .filter(Objects::nonNull) + .map(Element::ownText) + .findFirst() + .orElseThrow(() -> new ParsingException("Could not get comment text")); } @Override public String getUploaderName() throws ParsingException { - return writing.getElementsByClass("name").first().text(); + return writing.getElementsByClass("name").stream() + .filter(Objects::nonNull) + .map(Element::text) + .findFirst() + .orElseThrow(() -> new ParsingException("Could not get uploader name")); } @Override diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampExtractorHelper.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampExtractorHelper.java index 0d222d7b6..54c1a68eb 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampExtractorHelper.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampExtractorHelper.java @@ -8,6 +8,7 @@ import com.grack.nanojson.JsonParserException; import com.grack.nanojson.JsonWriter; import org.jsoup.Jsoup; +import org.jsoup.nodes.Element; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ReCaptchaException; @@ -19,6 +20,8 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Locale; +import javax.annotation.Nullable; + public final class BandcampExtractorHelper { public static final String BASE_URL = "https://bandcamp.com"; @@ -134,4 +137,14 @@ public final class BandcampExtractorHelper { throw new ParsingException("Could not parse date '" + textDate + "'", e); } } + + @Nullable + public static String getThumbnailUrlFromSearchResult(final Element searchResult) { + return searchResult.getElementsByClass("art").stream() + .flatMap(element -> element.getElementsByTag("img").stream()) + .map(element -> element.attr("src")) + .filter(string -> !string.isEmpty()) + .findFirst() + .orElse(null); + } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampPlaylistExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampPlaylistExtractor.java index 8f2477766..6bceb9ceb 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampPlaylistExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampPlaylistExtractor.java @@ -1,8 +1,15 @@ package org.schabi.newpipe.extractor.services.bandcamp.extractors; +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; + import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.schabi.newpipe.extractor.Page; @@ -17,15 +24,9 @@ import org.schabi.newpipe.extractor.services.bandcamp.extractors.streaminfoitem. import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; -import javax.annotation.Nonnull; import java.io.IOException; -import java.util.Objects; -import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper.getImageUrl; -import static org.schabi.newpipe.extractor.utils.JsonUtils.getJsonData; -import static org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampStreamExtractor.getAlbumInfoJson; -import static org.schabi.newpipe.extractor.utils.Utils.EMPTY_STRING; -import static org.schabi.newpipe.extractor.utils.Utils.HTTPS; +import javax.annotation.Nonnull; public class BandcampPlaylistExtractor extends PlaylistExtractor { @@ -92,12 +93,10 @@ public class BandcampPlaylistExtractor extends PlaylistExtractor { @Override public String getUploaderAvatarUrl() { - try { - return Objects.requireNonNull(document.getElementsByClass("band-photo").first()) - .attr("src"); - } catch (final NullPointerException e) { - return EMPTY_STRING; - } + return document.getElementsByClass("band-photo").stream() + .map(element -> element.attr("src")) + .findFirst() + .orElse(EMPTY_STRING); } @Override diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampPlaylistInfoItemExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampPlaylistInfoItemExtractor.java index 504eb350a..e31344ea7 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampPlaylistInfoItemExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampPlaylistInfoItemExtractor.java @@ -38,12 +38,6 @@ public class BandcampPlaylistInfoItemExtractor implements PlaylistInfoItemExtrac @Override public String getThumbnailUrl() { - final Element img = searchResult.getElementsByClass("art").first() - .getElementsByTag("img").first(); - if (img != null) { - return img.attr("src"); - } else { - return null; - } + return BandcampExtractorHelper.getThumbnailUrlFromSearchResult(searchResult); } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampRadioStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampRadioStreamExtractor.java index 9e6e5acf3..639d2abb8 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampRadioStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampRadioStreamExtractor.java @@ -5,6 +5,7 @@ import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonParser; import com.grack.nanojson.JsonParserException; import org.jsoup.Jsoup; +import org.jsoup.nodes.Element; import org.schabi.newpipe.extractor.MediaFormat; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.StreamingService; @@ -77,9 +78,11 @@ public class BandcampRadioStreamExtractor extends BandcampStreamExtractor { @Nonnull @Override - public String getUploaderName() { - return Jsoup.parse(showInfo.getString("image_caption")) - .getElementsByTag("a").first().text(); + public String getUploaderName() throws ParsingException { + return Jsoup.parse(showInfo.getString("image_caption")).getElementsByTag("a").stream() + .map(Element::text) + .findFirst() + .orElseThrow(() -> new ParsingException("Could not get uploader name")); } @Nullable diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampSearchExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampSearchExtractor.java index e5a80f87d..a4fdfd270 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampSearchExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampSearchExtractor.java @@ -50,40 +50,31 @@ public class BandcampSearchExtractor extends SearchExtractor { public InfoItemsPage getPage(final Page page) throws IOException, ExtractionException { - final String html = getDownloader().get(page.getUrl()).responseBody(); - final MultiInfoItemsCollector collector = new MultiInfoItemsCollector(getServiceId()); + final Document d = Jsoup.parse(getDownloader().get(page.getUrl()).responseBody()); - - final Document d = Jsoup.parse(html); - - final Elements searchResultsElements = d.getElementsByClass("searchresult"); - - for (final Element searchResult : searchResultsElements) { - - final String type = searchResult.getElementsByClass("result-info").first() - .getElementsByClass("itemtype").first().text(); + for (final Element searchResult : d.getElementsByClass("searchresult")) { + final String type = searchResult.getElementsByClass("result-info").stream() + .flatMap(element -> element.getElementsByClass("itemtype").stream()) + .map(Element::text) + .findFirst() + .orElse(""); switch (type) { default: - continue; case "FAN": // don't display fan results break; - case "ARTIST": collector.commit(new BandcampChannelInfoItemExtractor(searchResult)); break; - case "ALBUM": collector.commit(new BandcampPlaylistInfoItemExtractor(searchResult)); break; - case "TRACK": collector.commit(new BandcampSearchStreamInfoItemExtractor(searchResult, null)); break; } - } // Count pages @@ -92,7 +83,10 @@ public class BandcampSearchExtractor extends SearchExtractor { return new InfoItemsPage<>(collector, null); } - final Elements pages = pageLists.first().getElementsByTag("li"); + final Elements pages = pageLists.stream() + .map(element -> element.getElementsByTag("li")) + .findFirst() + .orElseGet(Elements::new); // Find current page int currentPage = -1; diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampStreamExtractor.java index e082bd716..31514776a 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampStreamExtractor.java @@ -128,11 +128,10 @@ public class BandcampStreamExtractor extends StreamExtractor { @Nonnull @Override public String getUploaderAvatarUrl() { - try { - return document.getElementsByClass("band-photo").first().attr("src"); - } catch (final NullPointerException e) { - return ""; - } + return document.getElementsByClass("band-photo").stream() + .map(element -> element.attr("src")) + .findFirst() + .orElse(""); } @Nonnull diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampSuggestionExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampSuggestionExtractor.java index 67516b4fc..6cc43385d 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampSuggestionExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampSuggestionExtractor.java @@ -4,7 +4,6 @@ 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.JsonObject; import com.grack.nanojson.JsonParser; import com.grack.nanojson.JsonParserException; @@ -17,9 +16,9 @@ import org.schabi.newpipe.extractor.suggestion.SuggestionExtractor; import java.io.IOException; import java.net.URLEncoder; -import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; public class BandcampSuggestionExtractor extends SuggestionExtractor { @@ -36,20 +35,12 @@ public class BandcampSuggestionExtractor extends SuggestionExtractor { final JsonObject fuzzyResults = JsonParser.object().from(downloader .get(AUTOCOMPLETE_URL + URLEncoder.encode(query, "UTF-8")).responseBody()); - final JsonArray jsonArray = fuzzyResults.getObject("auto") - .getArray("results"); - - final List suggestions = new ArrayList<>(); - - for (final Object fuzzyResult : jsonArray) { - final String res = ((JsonObject) fuzzyResult).getString("name"); - - if (!suggestions.contains(res)) { - suggestions.add(res); - } - } - - return suggestions; + return fuzzyResults.getObject("auto").getArray("results").stream() + .filter(JsonObject.class::isInstance) + .map(JsonObject.class::cast) + .map(jsonObject -> jsonObject.getString("name")) + .distinct() + .collect(Collectors.toList()); } catch (final JsonParserException e) { return Collections.emptyList(); } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/streaminfoitem/BandcampSearchStreamInfoItemExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/streaminfoitem/BandcampSearchStreamInfoItemExtractor.java index 0fdf58a9c..5e585e7e0 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/streaminfoitem/BandcampSearchStreamInfoItemExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/streaminfoitem/BandcampSearchStreamInfoItemExtractor.java @@ -2,6 +2,7 @@ package org.schabi.newpipe.extractor.services.bandcamp.extractors.streaminfoitem import org.jsoup.nodes.Element; import org.schabi.newpipe.extractor.exceptions.ParsingException; +import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampExtractorHelper; import javax.annotation.Nullable; @@ -46,13 +47,7 @@ public class BandcampSearchStreamInfoItemExtractor extends BandcampStreamInfoIte @Override public String getThumbnailUrl() throws ParsingException { - final Element img = searchResult.getElementsByClass("art").first() - .getElementsByTag("img").first(); - if (img != null) { - return img.attr("src"); - } else { - return null; - } + return BandcampExtractorHelper.getThumbnailUrlFromSearchResult(searchResult); } @Override