33import com .grack .nanojson .JsonArray ;
44import com .grack .nanojson .JsonObject ;
55
6+ import org .schabi .newpipe .extractor .Image ;
7+ import org .schabi .newpipe .extractor .Image .ResolutionLevel ;
68import org .schabi .newpipe .extractor .InfoItemExtractor ;
79import org .schabi .newpipe .extractor .InfoItemsCollector ;
810import org .schabi .newpipe .extractor .Page ;
1416import org .schabi .newpipe .extractor .services .peertube .extractors .PeertubeStreamInfoItemExtractor ;
1517import org .schabi .newpipe .extractor .utils .JsonUtils ;
1618import org .schabi .newpipe .extractor .utils .Parser ;
17- import org .schabi .newpipe .extractor .utils .Utils ;
1819
20+ import javax .annotation .Nonnull ;
1921import java .time .Instant ;
2022import java .time .OffsetDateTime ;
2123import java .time .ZoneOffset ;
2224import java .time .format .DateTimeParseException ;
25+ import java .util .Collections ;
26+ import java .util .List ;
27+ import java .util .stream .Collectors ;
28+
29+ import static org .schabi .newpipe .extractor .Image .HEIGHT_UNKNOWN ;
30+ import static org .schabi .newpipe .extractor .Image .WIDTH_UNKNOWN ;
31+ import static org .schabi .newpipe .extractor .utils .Utils .isBlank ;
32+ import static org .schabi .newpipe .extractor .utils .Utils .isNullOrEmpty ;
2333
2434public final class PeertubeParsingHelper {
2535 public static final String START_KEY = "start" ;
@@ -32,7 +42,7 @@ private PeertubeParsingHelper() {
3242
3343 public static void validate (final JsonObject json ) throws ContentNotAvailableException {
3444 final String error = json .getString ("error" );
35- if (!Utils . isBlank (error )) {
45+ if (!isBlank (error )) {
3646 throw new ContentNotAvailableException (error );
3747 }
3848 }
@@ -53,7 +63,7 @@ public static Page getNextPage(final String prevPageUrl, final long total) {
5363 } catch (final Parser .RegexException e ) {
5464 return null ;
5565 }
56- if (Utils . isBlank (prevStart )) {
66+ if (isBlank (prevStart )) {
5767 return null ;
5868 }
5969
@@ -128,4 +138,138 @@ public static void collectItemsFrom(final InfoItemsCollector collector,
128138 }
129139 }
130140
141+ /**
142+ * Get avatars from a {@code ownerAccount} or a {@code videoChannel} {@link JsonObject}.
143+ *
144+ * <p>
145+ * If the {@code avatars} {@link JsonArray} is present and non null or empty, avatars will be
146+ * extracted from this array using {@link #getImagesFromAvatarOrBannerArray(String, JsonArray)}.
147+ * </p>
148+ *
149+ * <p>
150+ * If that's not the case, an avatar will extracted using the {@code avatar} {@link JsonObject}.
151+ * </p>
152+ *
153+ * <p>
154+ * Note that only images for which paths are not null and not empty will be added to the
155+ * unmodifiable {@link Image} list returned.
156+ * </p>
157+ *
158+ * @param baseUrl the base URL of the PeerTube instance
159+ * @param ownerAccountOrVideoChannelObject the {@code ownerAccount} or {@code videoChannel}
160+ * {@link JsonObject}
161+ * @return an unmodifiable list of {@link Image}s, which may be empty but never null
162+ */
163+ @ Nonnull
164+ public static List <Image > getAvatarsFromOwnerAccountOrVideoChannelObject (
165+ @ Nonnull final String baseUrl ,
166+ @ Nonnull final JsonObject ownerAccountOrVideoChannelObject ) {
167+ return getImagesFromAvatarsOrBanners (baseUrl , ownerAccountOrVideoChannelObject ,
168+ "avatars" , "avatar" );
169+ }
170+
171+ /**
172+ * Get banners from a {@code ownerAccount} or a {@code videoChannel} {@link JsonObject}.
173+ *
174+ * <p>
175+ * If the {@code banners} {@link JsonArray} is present and non null or empty, banners will be
176+ * extracted from this array using {@link #getImagesFromAvatarOrBannerArray(String, JsonArray)}.
177+ * </p>
178+ *
179+ * <p>
180+ * If that's not the case, a banner will extracted using the {@code banner} {@link JsonObject}.
181+ * </p>
182+ *
183+ * <p>
184+ * Note that only images for which paths are not null and not empty will be added to the
185+ * unmodifiable {@link Image} list returned.
186+ * </p>
187+ *
188+ * @param baseUrl the base URL of the PeerTube instance
189+ * @param ownerAccountOrVideoChannelObject the {@code ownerAccount} or {@code videoChannel}
190+ * {@link JsonObject}
191+ * @return an unmodifiable list of {@link Image}s, which may be empty but never null
192+ */
193+ @ Nonnull
194+ public static List <Image > getBannersFromAccountOrVideoChannelObject (
195+ @ Nonnull final String baseUrl ,
196+ @ Nonnull final JsonObject ownerAccountOrVideoChannelObject ) {
197+ return getImagesFromAvatarsOrBanners (baseUrl , ownerAccountOrVideoChannelObject ,
198+ "banners" , "banner" );
199+ }
200+
201+ /**
202+ * Utility method to get avatars and banners from video channels and accounts from given name
203+ * keys.
204+ *
205+ * <p>
206+ * Only images for which paths are not null and not empty will be added to the unmodifiable
207+ * {@link Image} list returned and only the width of avatars or banners is provided by the API,
208+ * and so is the only image dimension known.
209+ * </p>
210+ *
211+ * @param baseUrl the base URL of the PeerTube instance
212+ * @param ownerAccountOrVideoChannelObject the {@code ownerAccount} or {@code videoChannel}
213+ * {@link JsonObject}
214+ * @param jsonArrayName the key name of the {@link JsonArray} to which
215+ * extract all images available ({@code avatars} or
216+ * {@code banners})
217+ * @param jsonObjectName the key name of the {@link JsonObject} to which
218+ * extract a single image ({@code avatar} or
219+ * {@code banner}), used as a fallback if the images
220+ * {@link JsonArray} is null or empty
221+ * @return an unmodifiable list of {@link Image}s, which may be empty but never null
222+ */
223+ @ Nonnull
224+ private static List <Image > getImagesFromAvatarsOrBanners (
225+ @ Nonnull final String baseUrl ,
226+ @ Nonnull final JsonObject ownerAccountOrVideoChannelObject ,
227+ @ Nonnull final String jsonArrayName ,
228+ @ Nonnull final String jsonObjectName ) {
229+ final JsonArray images = ownerAccountOrVideoChannelObject .getArray (jsonArrayName );
230+
231+ if (!isNullOrEmpty (images )) {
232+ return getImagesFromAvatarOrBannerArray (baseUrl , images );
233+ }
234+
235+ final JsonObject image = ownerAccountOrVideoChannelObject .getObject (jsonObjectName );
236+ final String path = image .getString ("path" );
237+ if (!isNullOrEmpty (path )) {
238+ return List .of (new Image (baseUrl + path , HEIGHT_UNKNOWN ,
239+ image .getInt ("width" , WIDTH_UNKNOWN ), ResolutionLevel .UNKNOWN ));
240+ }
241+
242+ return List .of ();
243+ }
244+
245+ /**
246+ * Get {@link Image}s from an {@code avatars} or a {@code banners} {@link JsonArray}.
247+ *
248+ * <p>
249+ * Only images for which paths are not null and not empty will be added to the
250+ * unmodifiable {@link Image} list returned.
251+ * </p>
252+ *
253+ * <p>
254+ * Note that only the width of avatars or banners is provided by the API, and so only is the
255+ * only dimension known of images.
256+ * </p>
257+ *
258+ * @param baseUrl the base URL of the PeerTube instance from which the
259+ * {@code avatarsOrBannersArray} {@link JsonArray} comes from
260+ * @param avatarsOrBannersArray an {@code avatars} or {@code banners} {@link JsonArray}
261+ * @return an unmodifiable list of {@link Image}s, which may be empty but never null
262+ */
263+ @ Nonnull
264+ private static List <Image > getImagesFromAvatarOrBannerArray (
265+ @ Nonnull final String baseUrl ,
266+ @ Nonnull final JsonArray avatarsOrBannersArray ) {
267+ return avatarsOrBannersArray .stream ()
268+ .filter (JsonObject .class ::isInstance )
269+ .map (JsonObject .class ::cast )
270+ .filter (image -> !isNullOrEmpty (image .getString ("path" )))
271+ .map (image -> new Image (baseUrl + image .getString ("path" ), HEIGHT_UNKNOWN ,
272+ image .getInt ("width" , WIDTH_UNKNOWN ), ResolutionLevel .UNKNOWN ))
273+ .collect (Collectors .toUnmodifiableList ());
274+ }
131275}
0 commit comments