From 81c0d80a54f3b280957ba77908225e2cb91a591c Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Wed, 27 Jul 2022 19:30:59 +0200 Subject: [PATCH] [PeerTube] Add utility methods to get avatars and banners of accounts and channels Four new static methods have been added in PeertubeParsingHelper to do so: - two public methods to get the corresponding image type: getAvatarsFromOwnerAccountOrVideoChannelObject(String, JsonObject) and getBannersFromAccountOrVideoChannelObject(String, JsonObject); - two private methods as helper methods: getImagesFromAvatarsOrBanners(String, JsonObject, String, String) and getImagesFromAvatarOrBannerArray(String, JsonArray). --- .../peertube/PeertubeParsingHelper.java | 150 +++++++++++++++++- 1 file changed, 147 insertions(+), 3 deletions(-) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/PeertubeParsingHelper.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/PeertubeParsingHelper.java index b57aa6b88..ad11e6b39 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/PeertubeParsingHelper.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/PeertubeParsingHelper.java @@ -3,6 +3,8 @@ package org.schabi.newpipe.extractor.services.peertube; import com.grack.nanojson.JsonArray; import com.grack.nanojson.JsonObject; +import org.schabi.newpipe.extractor.Image; +import org.schabi.newpipe.extractor.Image.ResolutionLevel; import org.schabi.newpipe.extractor.InfoItemExtractor; import org.schabi.newpipe.extractor.InfoItemsCollector; import org.schabi.newpipe.extractor.Page; @@ -14,12 +16,20 @@ import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeSepiaSt import org.schabi.newpipe.extractor.services.peertube.extractors.PeertubeStreamInfoItemExtractor; import org.schabi.newpipe.extractor.utils.JsonUtils; import org.schabi.newpipe.extractor.utils.Parser; -import org.schabi.newpipe.extractor.utils.Utils; +import javax.annotation.Nonnull; import java.time.Instant; import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeParseException; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import static org.schabi.newpipe.extractor.Image.HEIGHT_UNKNOWN; +import static org.schabi.newpipe.extractor.Image.WIDTH_UNKNOWN; +import static org.schabi.newpipe.extractor.utils.Utils.isBlank; +import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; public final class PeertubeParsingHelper { public static final String START_KEY = "start"; @@ -32,7 +42,7 @@ public final class PeertubeParsingHelper { public static void validate(final JsonObject json) throws ContentNotAvailableException { final String error = json.getString("error"); - if (!Utils.isBlank(error)) { + if (!isBlank(error)) { throw new ContentNotAvailableException(error); } } @@ -53,7 +63,7 @@ public final class PeertubeParsingHelper { } catch (final Parser.RegexException e) { return null; } - if (Utils.isBlank(prevStart)) { + if (isBlank(prevStart)) { return null; } @@ -128,4 +138,138 @@ public final class PeertubeParsingHelper { } } + /** + * Get avatars from a {@code ownerAccount} or a {@code videoChannel} {@link JsonObject}. + * + *

+ * If the {@code avatars} {@link JsonArray} is present and non null or empty, avatars will be + * extracted from this array using {@link #getImagesFromAvatarOrBannerArray(String, JsonArray)}. + *

+ * + *

+ * If that's not the case, an avatar will extracted using the {@code avatar} {@link JsonObject}. + *

+ * + *

+ * Note that only images for which paths are not null and not empty will be added to the + * unmodifiable {@link Image} list returned. + *

+ * + * @param baseUrl the base URL of the PeerTube instance + * @param ownerAccountOrVideoChannelObject the {@code ownerAccount} or {@code videoChannel} + * {@link JsonObject} + * @return an unmodifiable list of {@link Image}s, which may be empty but never null + */ + @Nonnull + public static List getAvatarsFromOwnerAccountOrVideoChannelObject( + @Nonnull final String baseUrl, + @Nonnull final JsonObject ownerAccountOrVideoChannelObject) { + return getImagesFromAvatarsOrBanners(baseUrl, ownerAccountOrVideoChannelObject, + "avatars", "avatar"); + } + + /** + * Get banners from a {@code ownerAccount} or a {@code videoChannel} {@link JsonObject}. + * + *

+ * If the {@code banners} {@link JsonArray} is present and non null or empty, banners will be + * extracted from this array using {@link #getImagesFromAvatarOrBannerArray(String, JsonArray)}. + *

+ * + *

+ * If that's not the case, a banner will extracted using the {@code banner} {@link JsonObject}. + *

+ * + *

+ * Note that only images for which paths are not null and not empty will be added to the + * unmodifiable {@link Image} list returned. + *

+ * + * @param baseUrl the base URL of the PeerTube instance + * @param ownerAccountOrVideoChannelObject the {@code ownerAccount} or {@code videoChannel} + * {@link JsonObject} + * @return an unmodifiable list of {@link Image}s, which may be empty but never null + */ + @Nonnull + public static List getBannersFromAccountOrVideoChannelObject( + @Nonnull final String baseUrl, + @Nonnull final JsonObject ownerAccountOrVideoChannelObject) { + return getImagesFromAvatarsOrBanners(baseUrl, ownerAccountOrVideoChannelObject, + "banners", "banner"); + } + + /** + * Utility method to get avatars and banners from video channels and accounts from given name + * keys. + * + *

+ * Only images for which paths are not null and not empty will be added to the unmodifiable + * {@link Image} list returned and only the width of avatars or banners is provided by the API, + * and so is the only image dimension known. + *

+ * + * @param baseUrl the base URL of the PeerTube instance + * @param ownerAccountOrVideoChannelObject the {@code ownerAccount} or {@code videoChannel} + * {@link JsonObject} + * @param jsonArrayName the key name of the {@link JsonArray} to which + * extract all images available ({@code avatars} or + * {@code banners}) + * @param jsonObjectName the key name of the {@link JsonObject} to which + * extract a single image ({@code avatar} or + * {@code banner}), used as a fallback if the images + * {@link JsonArray} is null or empty + * @return an unmodifiable list of {@link Image}s, which may be empty but never null + */ + @Nonnull + private static List getImagesFromAvatarsOrBanners( + @Nonnull final String baseUrl, + @Nonnull final JsonObject ownerAccountOrVideoChannelObject, + @Nonnull final String jsonArrayName, + @Nonnull final String jsonObjectName) { + final JsonArray images = ownerAccountOrVideoChannelObject.getArray(jsonArrayName); + + if (!isNullOrEmpty(images)) { + return getImagesFromAvatarOrBannerArray(baseUrl, images); + } + + final JsonObject image = ownerAccountOrVideoChannelObject.getObject(jsonObjectName); + final String path = image.getString("path"); + if (!isNullOrEmpty(path)) { + return List.of(new Image(baseUrl + path, HEIGHT_UNKNOWN, + image.getInt("width", WIDTH_UNKNOWN), ResolutionLevel.UNKNOWN)); + } + + return List.of(); + } + + /** + * Get {@link Image}s from an {@code avatars} or a {@code banners} {@link JsonArray}. + * + *

+ * Only images for which paths are not null and not empty will be added to the + * unmodifiable {@link Image} list returned. + *

+ * + *

+ * Note that only the width of avatars or banners is provided by the API, and so only is the + * only dimension known of images. + *

+ * + * @param baseUrl the base URL of the PeerTube instance from which the + * {@code avatarsOrBannersArray} {@link JsonArray} comes from + * @param avatarsOrBannersArray an {@code avatars} or {@code banners} {@link JsonArray} + * @return an unmodifiable list of {@link Image}s, which may be empty but never null + */ + @Nonnull + private static List getImagesFromAvatarOrBannerArray( + @Nonnull final String baseUrl, + @Nonnull final JsonArray avatarsOrBannersArray) { + return avatarsOrBannersArray.stream() + .filter(JsonObject.class::isInstance) + .map(JsonObject.class::cast) + .filter(image -> !isNullOrEmpty(image.getString("path"))) + .map(image -> new Image(baseUrl + image.getString("path"), HEIGHT_UNKNOWN, + image.getInt("width", WIDTH_UNKNOWN), ResolutionLevel.UNKNOWN)) + .collect(Collectors.toUnmodifiableList()); + } }