From 9e33c003bf91a676a319013f0679b2c7e51a6e28 Mon Sep 17 00:00:00 2001 From: Redouane Bali Date: Fri, 21 Jan 2022 10:42:03 +0100 Subject: [PATCH] feat: pagination for likes and retweets endpoints (#353) * feat: pagination for likes and retweets endpoints --- .gitignore | 9 +--- pom.xml | 2 +- .../redouane59/twitter/ITwitterClientV2.java | 18 ++++++- .../redouane59/twitter/TwitterClient.java | 52 ++++++++++++++++--- .../twitter/nrt/ITwitterClientV2Test.java | 44 ++++++++++++++-- test-twitter-credentials.json | 6 --- 6 files changed, 103 insertions(+), 28 deletions(-) delete mode 100644 test-twitter-credentials.json diff --git a/.gitignore b/.gitignore index 7428b706..d5938946 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,9 @@ +test-twitter-credentials.json /.idea/libraries /.idea/*.xml /.target *.iml *.class -src/main/resources/twitter-credentials.json -src/main/resources/twitter-credentials2.json -src/main/java/com/socialmediaraiser/okhttpCache/ -src/main/java/io/github/redouane59/okhttpCache/ -src/main/java/com/socialmediaraiser/okhttpCache/* -src/main/java/io/github/redouane59/okhttpCache/* target/ */target/** */target/* @@ -17,8 +12,6 @@ target/ /okhttpCache/* *.asc bundle.jar -test-twitter-credentials.json - /.vscode /.settings .classpath diff --git a/pom.xml b/pom.xml index 8f2a7e14..9b7b8ede 100644 --- a/pom.xml +++ b/pom.xml @@ -194,5 +194,5 @@ https://github.com/Redouane59/twittered - 2.15-SNAPSHOT + 2.15 \ No newline at end of file diff --git a/src/main/java/io/github/redouane59/twitter/ITwitterClientV2.java b/src/main/java/io/github/redouane59/twitter/ITwitterClientV2.java index bacf3719..e3e009c3 100644 --- a/src/main/java/io/github/redouane59/twitter/ITwitterClientV2.java +++ b/src/main/java/io/github/redouane59/twitter/ITwitterClientV2.java @@ -361,12 +361,20 @@ public interface ITwitterClientV2 { LikeResponse unlikeTweet(String tweetId); /** - * Allows you to get information about a Tweet’s liking users calling https://api.twitter.com/2/tweets/:id/liking_users + * Allows you to get information about a Tweet’s all liking users calling https://api.twitter.com/2/tweets/:id/liking_users * * @param tweetId ID of the Tweet to request liking users of. */ UserList getLikingUsers(String tweetId); + /** + * Allows you to get information about a Tweet’s liking users calling https://api.twitter.com/2/tweets/:id/liking_users + * + * @param tweetId ID of the Tweet to request liking users of. + * @param maxResults the maximum results to be returned. + */ + UserList getLikingUsers(String tweetId, int maxResults); + /** * Allows you to get information about a user’s liked Tweets calling https://api.twitter.com/2/users/:id/liked_tweets * @@ -443,6 +451,14 @@ public interface ITwitterClientV2 { * Allows you to get information about who has Retweeted a Tweet calling https://api.twitter.com/2/tweets/:id/retweeted_by * * @param tweetId the id of the tweet + * @param maxResults the maximum results to be returned. + */ + UserList getRetweetingUsers(String tweetId, int maxResults); + + /** + * Allows you to get information about all users who have Retweeted a Tweet calling https://api.twitter.com/2/tweets/:id/retweeted_by + * + * @param tweetId the id of the tweet */ UserList getRetweetingUsers(String tweetId); diff --git a/src/main/java/io/github/redouane59/twitter/TwitterClient.java b/src/main/java/io/github/redouane59/twitter/TwitterClient.java index b7e5e288..3815332b 100644 --- a/src/main/java/io/github/redouane59/twitter/TwitterClient.java +++ b/src/main/java/io/github/redouane59/twitter/TwitterClient.java @@ -448,20 +448,58 @@ public LikeResponse unlikeTweet(String tweetId) { } @Override - public UserList getRetweetingUsers(String tweetId) { - String url = urlHelper.getRetweetersUrl(tweetId); + public UserList getRetweetingUsers(String tweetId, int maxResults) { + String url = urlHelper.getRetweetersUrl(tweetId); + return getUsersRecursively(maxResults, url); + } + + + /** + * Used for get liking users and get retweeting users endpoints recursively calls + */ + private UserList getUsersRecursively(int maxResults, String url) { Map parameters = new HashMap<>(); parameters.put(USER_FIELDS, ALL_USER_FIELDS); parameters.put(EXPANSION, PINNED_TWEET_ID); - return getRequestHelper().getRequestWithParameters(url, parameters, UserList.class).orElseThrow(NoSuchElementException::new); + UserList result = UserList.builder().data(new ArrayList<>()).meta(new UserMeta()).build(); + String next; + + do { + parameters.put(MAX_RESULTS, String.valueOf(Math.min(100, maxResults - result.getData().size()))); + Optional userList = getRequestHelper().getRequestWithParameters(url, parameters, UserList.class); + if (!userList.isPresent() || userList.get().getData() == null) { + result.getMeta().setNextToken(null); + break; + } + result.getData().addAll(userList.get().getData()); + + UserMeta meta = UserMeta.builder() + .resultCount(result.getData().size()) + .nextToken(userList.get().getMeta().getNextToken()) + .build(); + result.setMeta(meta); + next = userList.get().getMeta().getNextToken(); + parameters.put(AdditionalParameters.PAGINATION_TOKEN, next); + } while (next != null && result.getData().size() < maxResults); + + return result; + } + + + @Override + public UserList getRetweetingUsers(String tweetId) { + return getRetweetingUsers(tweetId, Integer.MAX_VALUE); + } + + @Override + public UserList getLikingUsers(final String tweetId, int maxResults) { + String url = getUrlHelper().getLikingUsersUrl(tweetId); + return getUsersRecursively(maxResults, url); } @Override public UserList getLikingUsers(final String tweetId) { - String url = getUrlHelper().getLikingUsersUrl(tweetId); - Map parameters = new HashMap<>(); - parameters.put(USER_FIELDS, ALL_USER_FIELDS); - return getRequestHelper().getRequestWithParameters(url, parameters, UserList.class).orElseThrow(NoSuchElementException::new); + return getLikingUsers(tweetId, Integer.MAX_VALUE); } @Override diff --git a/src/test/java/io/github/redouane59/twitter/nrt/ITwitterClientV2Test.java b/src/test/java/io/github/redouane59/twitter/nrt/ITwitterClientV2Test.java index 829f5c4c..72189a4d 100644 --- a/src/test/java/io/github/redouane59/twitter/nrt/ITwitterClientV2Test.java +++ b/src/test/java/io/github/redouane59/twitter/nrt/ITwitterClientV2Test.java @@ -446,14 +446,31 @@ public void testGetTweetByIdWithExpansions() { } @Test - public void testGetLikingUsers() { + public void testGetAllLikingUsers() { UserList result = twitterClient.getLikingUsers("1395447825366847488"); assertNotNull(result.getData().get(0).getId()); assertNotNull(result.getData().get(0).getName()); assertNotNull(result.getData().get(0).getDisplayedName()); assertNotNull(result.getData().get(0).getProfileImageUrl()); assertNotNull(result.getData().get(0).getCreatedAt()); - assertTrue(result.getData().size() > 40); + assertTrue(result.getData().size() > 105); + } + + @Test + public void testGetLikingUsersWithMaxResults() { + UserList result = twitterClient.getLikingUsers("1395447825366847488", 100); + assertNotNull(result.getData().get(0).getId()); + assertNotNull(result.getData().get(0).getName()); + assertNotNull(result.getData().get(0).getDisplayedName()); + assertNotNull(result.getData().get(0).getProfileImageUrl()); + assertNotNull(result.getData().get(0).getCreatedAt()); + assertEquals(100, result.getData().size()); + result = twitterClient.getLikingUsers("1395447825366847488", 50); + assertEquals(50, result.getData().size()); + result = twitterClient.getLikingUsers("1395447825366847488", 999999); + assertTrue(result.getData().size() > 100); + assertTrue(result.getData().size() < 1000); + } @Test @@ -514,17 +531,34 @@ public void testGetAllTweetCountWithParams() { } @Test - public void testGetRetweetingUsers() { - String tweetId = "1415348607813832708"; + public void testAllGetRetweetingUsers() { + String tweetId = "1460323737035677698"; UserList result = twitterClient.getRetweetingUsers(tweetId); assertNotNull(result.getData()); - assertTrue(result.getData().size() > 10); + assertTrue(result.getData().size() > 200); + assertTrue(result.getData().size() < 400); assertNotNull(result.getData().get(0).getId()); assertNotNull(result.getData().get(0).getName()); assertNotNull(result.getData().get(0).getDisplayedName()); assertNotNull(result.getData().get(0).getDateOfCreation()); } + @Test + public void testGetRetweetingUsersWithMaxResults() { + String tweetId = "1460323737035677698"; + UserList result = twitterClient.getRetweetingUsers(tweetId, 50); + assertNotNull(result.getData()); + assertNotNull(result.getData().get(0).getId()); + assertNotNull(result.getData().get(0).getName()); + assertNotNull(result.getData().get(0).getDisplayedName()); + assertNotNull(result.getData().get(0).getDateOfCreation()); + assertEquals(50, result.getData().size()); + result = twitterClient.getRetweetingUsers(tweetId, 150); + assertEquals(150, result.getData().size()); + + + } + @Test public void testSpacesSearchAndLookup() { SpaceState expectedState = SpaceState.LIVE; diff --git a/test-twitter-credentials.json b/test-twitter-credentials.json deleted file mode 100644 index f8233470..00000000 --- a/test-twitter-credentials.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "apiKey": "REPLACE ME", - "apiSecretKey": "REPLACE ME", - "accessToken": "REPLACE ME", - "accessTokenSecret": "REPLACE ME" -} \ No newline at end of file