22
33import com .github .instagram4j .instagram4j .IGClient ;
44import com .github .instagram4j .instagram4j .actions .users .UserAction ;
5+ import com .github .instagram4j .instagram4j .models .direct .IGThread ;
6+ import com .github .instagram4j .instagram4j .models .direct .item .ThreadItem ;
7+ import com .github .instagram4j .instagram4j .models .direct .item .ThreadTextItem ;
8+ import com .github .instagram4j .instagram4j .models .media .timeline .TimelineMedia ;
59import com .github .instagram4j .instagram4j .models .user .Profile ;
610import com .github .instagram4j .instagram4j .models .user .User ;
711import com .github .instagram4j .instagram4j .requests .IGRequest ;
12+ import com .github .instagram4j .instagram4j .requests .direct .DirectInboxRequest ;
13+ import com .github .instagram4j .instagram4j .requests .direct .DirectThreadsRequest ;
14+ import com .github .instagram4j .instagram4j .requests .feed .FeedTimelineRequest ;
815import com .github .instagram4j .instagram4j .requests .friendships .FriendshipsActionRequest ;
16+ import com .github .instagram4j .instagram4j .requests .media .MediaInfoRequest ;
917import com .github .instagram4j .instagram4j .responses .IGResponse ;
18+ import com .github .instagram4j .instagram4j .responses .feed .FeedTimelineResponse ;
1019import com .github .instagram4j .instagram4j .responses .feed .FeedUsersResponse ;
20+ import com .xcoder .easyinsta .exceptions .InstagramException ;
21+ import com .xcoder .easyinsta .exceptions .Reasons ;
22+
23+ import org .jetbrains .annotations .NotNull ;
24+ import org .jetbrains .annotations .Nullable ;
25+
1126import java .io .File ;
1227import java .io .FileInputStream ;
1328import java .io .IOException ;
1429import java .util .ArrayList ;
30+ import java .util .Collection ;
31+ import java .util .Collections ;
1532import java .util .List ;
33+ import java .util .Objects ;
1634import java .util .concurrent .CompletableFuture ;
1735import java .util .concurrent .CompletionException ;
1836import java .util .concurrent .ExecutionException ;
37+ import java .util .concurrent .atomic .AtomicInteger ;
1938import java .util .function .Consumer ;
2039import java .util .function .Function ;
40+ import java .util .function .Predicate ;
41+ import java .util .stream .Collectors ;
2142
2243class Utils {
2344 private static IGClient client ;
2445 private Object meta ;
25- protected Utils (IGClient client ){
46+
47+
48+ protected Utils (IGClient client ) {
2649 Utils .client = client ;
2750 }
2851
29- protected <T extends IGResponse > Task <String > request (IGRequest <T > request ) throws CompletionException {
30- Task <String > task = new Task <>();
31- CompletableFuture <T > response = client .sendRequest (request );
32- response .thenAccept (new Consumer <IGResponse >() {
52+ public <T extends IGResponse > Task <Void > request (IGRequest <T > request ) throws CompletionException {
53+ Task <Void > task = new Task <>();
54+ client .sendRequest (request ).exceptionally (new Function <Throwable , T >() {
3355 @ Override
34- public void accept (IGResponse igResponse ) {
35- task .value = igResponse .getMessage ();
36- }
37- }).exceptionally (new Function <Throwable , Void >() {
38- @ Override
39- public Void apply (Throwable throwable ) {
56+ public T apply (Throwable throwable ) {
4057 task .exception = throwable ;
4158 return null ;
4259 }
@@ -45,25 +62,25 @@ public Void apply(Throwable throwable) {
4562 }
4663
4764
48- protected byte [] readFile (File file ) throws IOException {
65+ byte [] readFile (File file ) throws IOException {
4966 FileInputStream in = new FileInputStream (file );
5067 byte [] bytes = new byte [in .available ()];
5168 in .read (bytes );
5269 return bytes ;
5370 }
5471
5572
56- protected Task <String > followAction (String username , FriendshipsActionRequest .FriendshipsAction action ){
73+ protected Task <Void > followAction (String username , FriendshipsActionRequest .FriendshipsAction action ) {
5774 try {
5875 User user = client .actions ().users ().findByUsername (username ).get ().getUser ();
59- return request (new FriendshipsActionRequest (user .getPk (),action ));
76+ return request (new FriendshipsActionRequest (user .getPk (), action ));
6077 } catch (ExecutionException | InterruptedException e ) {
6178 return new Task <>(e );
6279 }
6380 }
6481
6582
66- protected Object getProfileMetadata (CompletableFuture <UserAction > response , String what ){
83+ protected Object getProfileMetadata (CompletableFuture <UserAction > response , String what ) {
6784 try {
6885 response .thenAccept (new Consumer <UserAction >() {
6986 @ Override
@@ -81,8 +98,9 @@ public void accept(UserAction userAction) {
8198 case "followings" :
8299 meta = userAction .getUser ().getFollowing_count ();
83100 break ;
84- default :
101+ case "posts" :
85102 meta = userAction .getUser ().getMedia_count ();
103+ break ;
86104 }
87105 }
88106 }).exceptionally (new Function <Throwable , Void >() {
@@ -93,12 +111,13 @@ public Void apply(Throwable throwable) {
93111 }
94112 }).join ();
95113 return meta ;
96- } catch (CompletionException e ){
114+ } catch (CompletionException e ) {
97115 return e ;
98116 }
99117 }
100118
101- protected Task <List <String >> getFeeds (CompletableFuture <UserAction > response ,boolean isFollowersFeed ){
119+
120+ protected Task <List <String >> getFeeds (CompletableFuture <UserAction > response , boolean isFollowersFeed ) {
102121 Task <List <String >> task = new Task <>();
103122 List <String > list = new ArrayList <>();
104123 try {
@@ -120,8 +139,89 @@ public Void apply(Throwable throwable) {
120139 }
121140 }).join ();
122141 return task ;
123- } catch (CompletionException e ){
142+ } catch (CompletionException e ) {
124143 return new Task <>(e );
125144 }
126145 }
146+
147+ @ NotNull
148+ protected IGThread getThread (String username ) throws ExecutionException , InterruptedException {
149+ List <IGThread > threads = client .sendRequest (new DirectInboxRequest ()).get ().getInbox ().getThreads ();
150+ for (IGThread thread : threads )
151+ for (Profile user : thread .getUsers ()) {
152+ if (user .getUsername ().equals (username )) {
153+ return thread ;
154+ }
155+ }
156+ throw new InstagramException ("There is no user with username " + username , Reasons .INVALID_USERNAME );
157+ }
158+
159+
160+ protected List <ThreadItem > getThreadItem (String username , int count , boolean onlySent , @ Nullable Instagram .OnProgressListener listener ) throws ExecutionException , InterruptedException {
161+ List <ThreadItem > list = new ArrayList <>();
162+ IGThread thread = getThread (username );
163+ String cursor = thread .getOldest_cursor ();
164+ list .add (thread .getItems ().get (0 ));
165+ if (count > 20 ) {
166+ int loop = (count /20 ) + (count %20 == 0 ? 0 : 1 );
167+ for (int i = 0 ; i < loop ; i ++){
168+ thread = client .sendRequest (new DirectThreadsRequest (thread .getThread_id (), cursor )).get ().getThread ();
169+ list .addAll (thread .getItems ());
170+ cursor = thread .getOldest_cursor ();
171+ if (listener != null )
172+ listener .onProgress ((i + 1 )*100 /loop );
173+ if (cursor == null )
174+ break ;
175+ }
176+ } else if (count == 0 ) {
177+ while (cursor != null ) {
178+ thread = client .sendRequest (new DirectThreadsRequest (thread .getThread_id (), cursor )).get ().getThread ();
179+ list .addAll (thread .getItems ());
180+ cursor = thread .getOldest_cursor ();
181+ }
182+ } else {
183+ while (list .size () < count ) {
184+ thread = client .sendRequest (new DirectThreadsRequest (thread .getThread_id (), cursor )).get ().getThread ();
185+ list .addAll (thread .getItems ());
186+ cursor = thread .getOldest_cursor ();
187+ if (cursor == null )
188+ break ;
189+ }
190+ }
191+ list .removeIf (threadItem -> onlySent && !isMessageSent (threadItem ));
192+ return list .stream ().limit (count == 0 ? list .size () : count ).collect (Collectors .toList ());
193+ }
194+
195+
196+ protected List <ThreadItem > getThreadItem (String username , String from , int frequency , boolean onlySent , @ Nullable Instagram .OnProgressListener listener ) throws IllegalArgumentException , ExecutionException , InterruptedException {
197+ List <ThreadItem > items = getThreadItem (username , 0 , onlySent ,listener );
198+ List <String > messages = items
199+ .stream ()
200+ .map (threadItem -> threadItem instanceof ThreadTextItem ? ((ThreadTextItem ) threadItem ).getText () : null )
201+ .filter (Objects ::nonNull )
202+ .collect (Collectors .toList ());
203+
204+
205+ if (frequency == 0 ){
206+ frequency = Collections .frequency (messages ,from );
207+ } else if (frequency < 0 )
208+ throw new IllegalArgumentException ("Frequency can't be negative" );
209+
210+ List <ThreadItem > threadItems = new ArrayList <>();
211+ for (ThreadItem item : items ) {
212+ threadItems .add (item );
213+ if (item instanceof ThreadTextItem && ((ThreadTextItem ) item ).getText ().equals (from )){
214+ if (frequency == 1 )
215+ return threadItems ;
216+ else
217+ frequency --;
218+ }
219+ }
220+ throw new IllegalArgumentException ("There is no such message '" + from + "' in the chat" );
221+ }
222+
223+
224+ protected boolean isMessageSent (ThreadItem item ) {
225+ return client .getSelfProfile ().getPk () == item .getUser_id ();
226+ }
127227}
0 commit comments