[PeerTube] Add support for comment replies

This commit is contained in:
TobiGr 2022-12-01 14:05:05 +01:00
parent 41c8dce452
commit 4e66b2287e
2 changed files with 66 additions and 8 deletions

View File

@ -26,6 +26,12 @@ import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class PeertubeCommentsExtractor extends CommentsExtractor { public class PeertubeCommentsExtractor extends CommentsExtractor {
/**
* Use {@link #isReply()} to access this variable.
*/
private Boolean isReply = null;
public PeertubeCommentsExtractor(final StreamingService service, public PeertubeCommentsExtractor(final StreamingService service,
final ListLinkHandler uiHandler) { final ListLinkHandler uiHandler) {
super(service, uiHandler); super(service, uiHandler);
@ -35,12 +41,27 @@ public class PeertubeCommentsExtractor extends CommentsExtractor {
@Override @Override
public InfoItemsPage<CommentsInfoItem> getInitialPage() public InfoItemsPage<CommentsInfoItem> getInitialPage()
throws IOException, ExtractionException { throws IOException, ExtractionException {
if (isReply()) {
return getPage(new Page(getOriginalUrl()));
} else {
return getPage(new Page(getUrl() + "?" + START_KEY + "=0&" return getPage(new Page(getUrl() + "?" + START_KEY + "=0&"
+ COUNT_KEY + "=" + ITEMS_PER_PAGE)); + COUNT_KEY + "=" + ITEMS_PER_PAGE));
} }
}
private void collectCommentsFrom(final CommentsInfoItemsCollector collector, private boolean isReply() throws ParsingException {
final JsonObject json) 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"); final JsonArray contents = json.getArray("data");
for (final Object c : contents) { 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 @Override
public InfoItemsPage<CommentsInfoItem> getPage(final Page page) public InfoItemsPage<CommentsInfoItem> getPage(final Page page)
throws IOException, ExtractionException { throws IOException, ExtractionException {
@ -73,11 +108,17 @@ public class PeertubeCommentsExtractor extends CommentsExtractor {
if (json != null) { if (json != null) {
PeertubeParsingHelper.validate(json); PeertubeParsingHelper.validate(json);
final long total = json.getLong("total"); final long total;
final CommentsInfoItemsCollector collector final CommentsInfoItemsCollector collector
= new CommentsInfoItemsCollector(getServiceId()); = new CommentsInfoItemsCollector(getServiceId());
if (isReply() || json.has("children")) {
total = json.getArray("children").size();
collectRepliesFrom(collector, json);
} else {
total = json.getLong("total");
collectCommentsFrom(collector, json); collectCommentsFrom(collector, json);
}
return new InfoItemsPage<>(collector, return new InfoItemsPage<>(collector,
PeertubeParsingHelper.getNextPage(page.getUrl(), total)); PeertubeParsingHelper.getNextPage(page.getUrl(), total));

View File

@ -4,6 +4,7 @@ import com.grack.nanojson.JsonObject;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.schabi.newpipe.extractor.Page;
import org.schabi.newpipe.extractor.ServiceList; import org.schabi.newpipe.extractor.ServiceList;
import org.schabi.newpipe.extractor.comments.CommentsInfoItemExtractor; import org.schabi.newpipe.extractor.comments.CommentsInfoItemExtractor;
import org.schabi.newpipe.extractor.exceptions.ParsingException; 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.stream.Description;
import org.schabi.newpipe.extractor.utils.JsonUtils; import org.schabi.newpipe.extractor.utils.JsonUtils;
import javax.annotation.Nullable;
import java.util.Objects; import java.util.Objects;
public class PeertubeCommentsInfoItemExtractor implements CommentsInfoItemExtractor { public class PeertubeCommentsInfoItemExtractor implements CommentsInfoItemExtractor {
@ -29,7 +31,7 @@ public class PeertubeCommentsInfoItemExtractor implements CommentsInfoItemExtrac
@Override @Override
public String getUrl() throws ParsingException { public String getUrl() throws ParsingException {
return url; return url + "/" + getCommentId();
} }
@Override @Override
@ -101,4 +103,19 @@ public class PeertubeCommentsInfoItemExtractor implements CommentsInfoItemExtrac
return ServiceList.PeerTube.getChannelLHFactory() return ServiceList.PeerTube.getChannelLHFactory()
.fromId("accounts/" + name + "@" + host, baseUrl).getUrl(); .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();
}
} }