From 4e66b2287e6356c074fc9923f7317ef6b404360e Mon Sep 17 00:00:00 2001 From: TobiGr Date: Thu, 1 Dec 2022 14:05:05 +0100 Subject: [PATCH] [PeerTube] Add support for comment replies --- .../extractors/PeertubeCommentsExtractor.java | 55 ++++++++++++++++--- .../PeertubeCommentsInfoItemExtractor.java | 19 ++++++- 2 files changed, 66 insertions(+), 8 deletions(-) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeCommentsExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeCommentsExtractor.java index f0568823c..4b342c21d 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeCommentsExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeCommentsExtractor.java @@ -26,6 +26,12 @@ import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; import javax.annotation.Nonnull; public class PeertubeCommentsExtractor extends CommentsExtractor { + + /** + * Use {@link #isReply()} to access this variable. + */ + private Boolean isReply = null; + public PeertubeCommentsExtractor(final StreamingService service, final ListLinkHandler uiHandler) { super(service, uiHandler); @@ -35,12 +41,27 @@ public class PeertubeCommentsExtractor extends CommentsExtractor { @Override public InfoItemsPage getInitialPage() throws IOException, ExtractionException { - return getPage(new Page(getUrl() + "?" + START_KEY + "=0&" - + COUNT_KEY + "=" + ITEMS_PER_PAGE)); + if (isReply()) { + return getPage(new Page(getOriginalUrl())); + } else { + return getPage(new Page(getUrl() + "?" + START_KEY + "=0&" + + COUNT_KEY + "=" + ITEMS_PER_PAGE)); + } } - private void collectCommentsFrom(final CommentsInfoItemsCollector collector, - final JsonObject json) throws ParsingException { + private boolean isReply() throws ParsingException { + if (isReply == null) { + if (getOriginalUrl().contains("/videos/watch/")) { + isReply = false; + } else { + isReply = getOriginalUrl().contains("/comment-threads/"); + } + } + return isReply; + } + + private void collectCommentsFrom(@Nonnull final CommentsInfoItemsCollector collector, + @Nonnull final JsonObject json) throws ParsingException { final JsonArray contents = json.getArray("data"); for (final Object c : contents) { @@ -53,6 +74,20 @@ public class PeertubeCommentsExtractor extends CommentsExtractor { } } + private void collectRepliesFrom(@Nonnull final CommentsInfoItemsCollector collector, + @Nonnull final JsonObject json) throws ParsingException { + final JsonArray contents = json.getArray("children"); + + for (final Object c : contents) { + if (c instanceof JsonObject) { + final JsonObject item = ((JsonObject) c).getObject("comment"); + if (!item.getBoolean("isDeleted")) { + collector.commit(new PeertubeCommentsInfoItemExtractor(item, this)); + } + } + } + } + @Override public InfoItemsPage getPage(final Page page) throws IOException, ExtractionException { @@ -73,11 +108,17 @@ public class PeertubeCommentsExtractor extends CommentsExtractor { if (json != null) { PeertubeParsingHelper.validate(json); - final long total = json.getLong("total"); - + final long total; final CommentsInfoItemsCollector collector = new CommentsInfoItemsCollector(getServiceId()); - collectCommentsFrom(collector, json); + + if (isReply() || json.has("children")) { + total = json.getArray("children").size(); + collectRepliesFrom(collector, json); + } else { + total = json.getLong("total"); + collectCommentsFrom(collector, json); + } return new InfoItemsPage<>(collector, PeertubeParsingHelper.getNextPage(page.getUrl(), total)); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeCommentsInfoItemExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeCommentsInfoItemExtractor.java index 8ceb91317..42cb02030 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeCommentsInfoItemExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/peertube/extractors/PeertubeCommentsInfoItemExtractor.java @@ -4,6 +4,7 @@ import com.grack.nanojson.JsonObject; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; +import org.schabi.newpipe.extractor.Page; import org.schabi.newpipe.extractor.ServiceList; import org.schabi.newpipe.extractor.comments.CommentsInfoItemExtractor; import org.schabi.newpipe.extractor.exceptions.ParsingException; @@ -12,6 +13,7 @@ import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper; import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.extractor.utils.JsonUtils; +import javax.annotation.Nullable; import java.util.Objects; public class PeertubeCommentsInfoItemExtractor implements CommentsInfoItemExtractor { @@ -29,7 +31,7 @@ public class PeertubeCommentsInfoItemExtractor implements CommentsInfoItemExtrac @Override public String getUrl() throws ParsingException { - return url; + return url + "/" + getCommentId(); } @Override @@ -101,4 +103,19 @@ public class PeertubeCommentsInfoItemExtractor implements CommentsInfoItemExtrac return ServiceList.PeerTube.getChannelLHFactory() .fromId("accounts/" + name + "@" + host, baseUrl).getUrl(); } + + @Override + @Nullable + public Page getReplies() throws ParsingException { + if (JsonUtils.getNumber(item, "totalReplies").intValue() == 0) { + return null; + } + final String threadId = JsonUtils.getNumber(item, "threadId").toString(); + return new Page(url + "/" + threadId, threadId); + } + + @Override + public int getReplyCount() throws ParsingException { + return JsonUtils.getNumber(item, "totalReplies").intValue(); + } }