package org.schabi.newpipe.extractor.services.peertube.extractors; import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonParser; import com.grack.nanojson.JsonParserException; import org.schabi.newpipe.extractor.Page; import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.channel.ChannelExtractor; import org.schabi.newpipe.extractor.downloader.Downloader; import org.schabi.newpipe.extractor.downloader.Response; 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.services.peertube.PeertubeParsingHelper; import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeChannelLinkHandlerFactory; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; import org.schabi.newpipe.extractor.utils.JsonUtils; import org.schabi.newpipe.extractor.utils.Utils; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.IOException; import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.COUNT_KEY; import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.ITEMS_PER_PAGE; import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.START_KEY; import static org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper.collectStreamsFrom; import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; public class PeertubeChannelExtractor extends ChannelExtractor { private JsonObject json; private final String baseUrl; public PeertubeChannelExtractor(final StreamingService service, final ListLinkHandler linkHandler) throws ParsingException { super(service, linkHandler); this.baseUrl = getBaseUrl(); } @Override public String getAvatarUrl() { String value; try { value = JsonUtils.getString(json, "avatar.path"); } catch (final Exception e) { value = "/client/assets/images/default-avatar.png"; } return baseUrl + value; } @Override public String getBannerUrl() { return null; } @Override public String getFeedUrl() throws ParsingException { return getBaseUrl() + "/feeds/videos.xml?videoChannelId=" + json.get("id"); } @Override public long getSubscriberCount() { return json.getLong("followersCount"); } @Nullable @Override public String getDescription() { return json.getString("description"); } @Override public String getParentChannelName() throws ParsingException { return JsonUtils.getString(json, "ownerAccount.name"); } @Override public String getParentChannelUrl() throws ParsingException { return JsonUtils.getString(json, "ownerAccount.url"); } @Override public String getParentChannelAvatarUrl() { String value; try { value = JsonUtils.getString(json, "ownerAccount.avatar.path"); } catch (final Exception e) { value = "/client/assets/images/default-avatar.png"; } return baseUrl + value; } @Override public boolean isVerified() throws ParsingException { return false; } @Nonnull @Override public InfoItemsPage getInitialPage() throws IOException, ExtractionException { return getPage(new Page(baseUrl + "/api/v1/" + getId() + "/videos?" + START_KEY + "=0&" + COUNT_KEY + "=" + ITEMS_PER_PAGE)); } @Override public InfoItemsPage getPage(final Page page) throws IOException, ExtractionException { if (page == null || isNullOrEmpty(page.getUrl())) { throw new IllegalArgumentException("Page doesn't contain an URL"); } final Response response = getDownloader().get(page.getUrl()); JsonObject pageJson = null; if (response != null && !Utils.isBlank(response.responseBody())) { try { pageJson = JsonParser.object().from(response.responseBody()); } catch (final Exception e) { throw new ParsingException("Could not parse json data for channel info", e); } } if (pageJson != null) { PeertubeParsingHelper.validate(pageJson); final long total = pageJson.getLong("total"); final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId()); collectStreamsFrom(collector, pageJson, getBaseUrl()); return new InfoItemsPage<>(collector, PeertubeParsingHelper.getNextPage(page.getUrl(), total)); } else { throw new ExtractionException("Unable to get PeerTube channel info"); } } @Override public void onFetchPage(@Nonnull final Downloader downloader) throws IOException, ExtractionException { final Response response = downloader.get( baseUrl + PeertubeChannelLinkHandlerFactory.API_ENDPOINT + getId()); if (response != null) { setInitialData(response.responseBody()); } else { throw new ExtractionException("Unable to extract PeerTube channel data"); } } private void setInitialData(final String responseBody) throws ExtractionException { try { json = JsonParser.object().from(responseBody); } catch (final JsonParserException e) { throw new ExtractionException("Unable to extract PeerTube channel data", e); } if (json == null) { throw new ExtractionException("Unable to extract PeerTube channel data"); } } @Nonnull @Override public String getName() throws ParsingException { return JsonUtils.getString(json, "displayName"); } }