Merge pull request #1111 from FineFindus/feat/creator-reply
Add `hasCreatorReply()` to CommentsInfoItem
This commit is contained in:
commit
d6f5cba6e2
|
@ -30,6 +30,7 @@ public class CommentsInfoItem extends InfoItem {
|
|||
private int replyCount;
|
||||
@Nullable
|
||||
private Page replies;
|
||||
private boolean creatorReply;
|
||||
|
||||
public static final int NO_LIKE_COUNT = -1;
|
||||
public static final int NO_STREAM_POSITION = -1;
|
||||
|
@ -172,4 +173,13 @@ public class CommentsInfoItem extends InfoItem {
|
|||
public Page getReplies() {
|
||||
return this.replies;
|
||||
}
|
||||
|
||||
public void setCreatorReply(final boolean creatorReply) {
|
||||
this.creatorReply = creatorReply;
|
||||
}
|
||||
|
||||
public boolean hasCreatorReply() {
|
||||
return creatorReply;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -134,4 +134,12 @@ public interface CommentsInfoItemExtractor extends InfoItemExtractor {
|
|||
default Page getReplies() throws ParsingException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the comment was replied to by the creator.
|
||||
*/
|
||||
@Nullable
|
||||
default boolean hasCreatorReply() throws ParsingException {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,6 +101,13 @@ public final class CommentsInfoItemsCollector
|
|||
addError(e);
|
||||
}
|
||||
|
||||
try {
|
||||
resultItem.setCreatorReply(extractor.hasCreatorReply());
|
||||
} catch (final Exception e) {
|
||||
addError(e);
|
||||
}
|
||||
|
||||
|
||||
return resultItem;
|
||||
}
|
||||
|
||||
|
|
|
@ -148,4 +148,10 @@ public class PeertubeCommentsInfoItemExtractor implements CommentsInfoItemExtrac
|
|||
}
|
||||
return replyCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCreatorReply() {
|
||||
return item.has("totalRepliesFromVideoAuthor")
|
||||
&& item.getInt("totalRepliesFromVideoAuthor") > 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -277,4 +277,16 @@ public class YoutubeCommentsInfoItemExtractor implements CommentsInfoItemExtract
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCreatorReply() throws ParsingException {
|
||||
try {
|
||||
final JsonObject commentRepliesRenderer = JsonUtils.getObject(json,
|
||||
"replies.commentRepliesRenderer");
|
||||
return commentRepliesRenderer.has("viewRepliesCreatorThumbnail");
|
||||
} catch (final Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -127,26 +127,46 @@ public class PeertubeCommentsExtractorTest {
|
|||
*/
|
||||
public static class NestedComments {
|
||||
private static PeertubeCommentsExtractor extractor;
|
||||
private static InfoItemsPage<CommentsInfoItem> comments = null;
|
||||
|
||||
@BeforeAll
|
||||
public static void setUp() throws Exception {
|
||||
NewPipe.init(DownloaderTestImpl.getInstance());
|
||||
extractor = (PeertubeCommentsExtractor) PeerTube
|
||||
.getCommentsExtractor("https://share.tube/w/vxu4uTstUBAUromWwXGHrq");
|
||||
comments = extractor.getInitialPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetComments() throws IOException, ExtractionException {
|
||||
final InfoItemsPage<CommentsInfoItem> comments = extractor.getInitialPage();
|
||||
assertFalse(comments.getItems().isEmpty());
|
||||
final Optional<CommentsInfoItem> nestedCommentHeadOpt =
|
||||
comments.getItems()
|
||||
.stream()
|
||||
.filter(c -> c.getCommentId().equals("9770"))
|
||||
.findFirst();
|
||||
findCommentWithId("9770", comments.getItems());
|
||||
assertTrue(nestedCommentHeadOpt.isPresent());
|
||||
assertTrue(findNestedCommentWithId("9773", nestedCommentHeadOpt.get()), "The nested comment replies were not found");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHasCreatorReply() {
|
||||
assertCreatorReply("9770", true);
|
||||
assertCreatorReply("9852", false);
|
||||
assertCreatorReply("11239", false);
|
||||
}
|
||||
|
||||
private static void assertCreatorReply(final String id, final boolean expected) {
|
||||
final Optional<CommentsInfoItem> comment =
|
||||
findCommentWithId(id, comments.getItems());
|
||||
assertTrue(comment.isPresent());
|
||||
assertEquals(expected, comment.get().hasCreatorReply());
|
||||
}
|
||||
}
|
||||
|
||||
private static Optional<CommentsInfoItem> findCommentWithId(
|
||||
final String id, final List<CommentsInfoItem> comments) {
|
||||
return comments
|
||||
.stream()
|
||||
.filter(c -> c.getCommentId().equals(id))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
private static boolean findNestedCommentWithId(final String id, final CommentsInfoItem comment)
|
||||
|
|
|
@ -352,6 +352,49 @@ public class YoutubeCommentsExtractorTest {
|
|||
}
|
||||
}
|
||||
|
||||
public static class CreatorReply {
|
||||
private final static String url = "https://www.youtube.com/watch?v=bem4adjGKjE";
|
||||
private static YoutubeCommentsExtractor extractor;
|
||||
|
||||
@BeforeAll
|
||||
public static void setUp() throws Exception {
|
||||
YoutubeTestsUtils.ensureStateless();
|
||||
NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "creatorReply"));
|
||||
extractor = (YoutubeCommentsExtractor) YouTube
|
||||
.getCommentsExtractor(url);
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetCommentsAllData() throws IOException, ExtractionException {
|
||||
final InfoItemsPage<CommentsInfoItem> comments = extractor.getInitialPage();
|
||||
|
||||
DefaultTests.defaultTestListOfItems(YouTube, comments.getItems(), comments.getErrors());
|
||||
|
||||
boolean creatorReply = false;
|
||||
|
||||
for (final CommentsInfoItem c : comments.getItems()) {
|
||||
assertFalse(Utils.isBlank(c.getUploaderUrl()));
|
||||
assertFalse(Utils.isBlank(c.getUploaderName()));
|
||||
YoutubeTestsUtils.testImages(c.getUploaderAvatars());
|
||||
assertFalse(Utils.isBlank(c.getCommentId()));
|
||||
assertFalse(Utils.isBlank(c.getName()));
|
||||
assertFalse(Utils.isBlank(c.getTextualUploadDate()));
|
||||
assertNotNull(c.getUploadDate());
|
||||
YoutubeTestsUtils.testImages(c.getThumbnails());
|
||||
assertFalse(Utils.isBlank(c.getUrl()));
|
||||
assertTrue(c.getLikeCount() >= 0);
|
||||
assertFalse(Utils.isBlank(c.getCommentText().getContent()));
|
||||
if (c.hasCreatorReply()) {
|
||||
creatorReply = true;
|
||||
}
|
||||
}
|
||||
assertTrue(creatorReply, "No comments was replied to by creator");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class FormattingTest {
|
||||
|
||||
private final static String url = "https://www.youtube.com/watch?v=zYpyS2HaZHM";
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
{
|
||||
"request": {
|
||||
"httpMethod": "GET",
|
||||
"url": "https://www.youtube.com/sw.js",
|
||||
"headers": {
|
||||
"Origin": [
|
||||
"https://www.youtube.com"
|
||||
],
|
||||
"Referer": [
|
||||
"https://www.youtube.com"
|
||||
],
|
||||
"Accept-Language": [
|
||||
"en-GB, en;q\u003d0.9"
|
||||
]
|
||||
},
|
||||
"localization": {
|
||||
"languageCode": "en",
|
||||
"countryCode": "GB"
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"responseCode": 200,
|
||||
"responseMessage": "",
|
||||
"responseHeaders": {
|
||||
"access-control-allow-credentials": [
|
||||
"true"
|
||||
],
|
||||
"access-control-allow-origin": [
|
||||
"https://www.youtube.com"
|
||||
],
|
||||
"alt-svc": [
|
||||
"h3\u003d\":443\"; ma\u003d2592000,h3-29\u003d\":443\"; ma\u003d2592000"
|
||||
],
|
||||
"cache-control": [
|
||||
"private, max-age\u003d0"
|
||||
],
|
||||
"content-type": [
|
||||
"text/javascript; charset\u003dutf-8"
|
||||
],
|
||||
"cross-origin-opener-policy-report-only": [
|
||||
"same-origin; report-to\u003d\"youtube_main\""
|
||||
],
|
||||
"date": [
|
||||
"Mon, 09 Oct 2023 09:24:07 GMT"
|
||||
],
|
||||
"expires": [
|
||||
"Mon, 09 Oct 2023 09:24:07 GMT"
|
||||
],
|
||||
"origin-trial": [
|
||||
"AvC9UlR6RDk2crliDsFl66RWLnTbHrDbp+DiY6AYz/PNQ4G4tdUTjrHYr2sghbkhGQAVxb7jaPTHpEVBz0uzQwkAAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTcxOTUzMjc5OSwiaXNTdWJkb21haW4iOnRydWV9"
|
||||
],
|
||||
"p3p": [
|
||||
"CP\u003d\"This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl\u003den-GB for more info.\""
|
||||
],
|
||||
"permissions-policy": [
|
||||
"ch-ua-arch\u003d*, ch-ua-bitness\u003d*, ch-ua-full-version\u003d*, ch-ua-full-version-list\u003d*, ch-ua-model\u003d*, ch-ua-wow64\u003d*, ch-ua-form-factor\u003d*, ch-ua-platform\u003d*, ch-ua-platform-version\u003d*"
|
||||
],
|
||||
"report-to": [
|
||||
"{\"group\":\"youtube_main\",\"max_age\":2592000,\"endpoints\":[{\"url\":\"https://csp.withgoogle.com/csp/report-to/youtube_main\"}]}"
|
||||
],
|
||||
"server": [
|
||||
"ESF"
|
||||
],
|
||||
"set-cookie": [
|
||||
"YSC\u003dKuw7lsMYkCU; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
|
||||
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dTue, 12-Jan-2021 09:24:07 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
|
||||
"CONSENT\u003dPENDING+599; expires\u003dWed, 08-Oct-2025 09:24:07 GMT; path\u003d/; domain\u003d.youtube.com; Secure"
|
||||
],
|
||||
"strict-transport-security": [
|
||||
"max-age\u003d31536000"
|
||||
],
|
||||
"x-content-type-options": [
|
||||
"nosniff"
|
||||
],
|
||||
"x-frame-options": [
|
||||
"SAMEORIGIN"
|
||||
],
|
||||
"x-xss-protection": [
|
||||
"0"
|
||||
]
|
||||
},
|
||||
"responseBody": "\n self.addEventListener(\u0027install\u0027, event \u003d\u003e {\n event.waitUntil(self.skipWaiting());\n });\n self.addEventListener(\u0027activate\u0027, event \u003d\u003e {\n event.waitUntil(\n self.clients.claim().then(() \u003d\u003e self.registration.unregister()));\n });\n ",
|
||||
"latestUrl": "https://www.youtube.com/sw.js"
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue