Skip to content

Commit ae89116

Browse files
authored
re-written
1 parent 21c15fe commit ae89116

File tree

8 files changed

+806
-328
lines changed

8 files changed

+806
-328
lines changed

EasyInsta/build.gradle

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@ android {
99
defaultConfig {
1010
minSdkVersion 24
1111
targetSdkVersion 30
12-
versionCode 2
13-
versionName "2.0"
12+
versionCode 25
13+
versionName "2.5"
1414

15-
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16-
consumerProguardFiles "consumer-rules.pro"
1715
}
1816

1917
buildTypes {

EasyInsta/src/main/java/com/xcoder/easyinsta/Instagram.java

Lines changed: 632 additions & 304 deletions
Large diffs are not rendered by default.

EasyInsta/src/main/java/com/xcoder/easyinsta/Task.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package com.xcoder.easyinsta;
22

3+
import org.jetbrains.annotations.NotNull;
4+
35
public final class Task<T> {
46
protected T value;
57
protected Throwable exception;
68

7-
protected Task(Exception e) {
9+
public Task(Exception e) {
810
exception = e;
911
}
1012

@@ -28,6 +30,7 @@ public void addOnCompleteListener(OnCompletionListener<T> callback) {
2830
callback.onComplete(this);
2931
}
3032

33+
@NotNull
3134
public T getValue() {
3235
return value;
3336
}

EasyInsta/src/main/java/com/xcoder/easyinsta/Utils.java

Lines changed: 119 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,58 @@
22

33
import com.github.instagram4j.instagram4j.IGClient;
44
import 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;
59
import com.github.instagram4j.instagram4j.models.user.Profile;
610
import com.github.instagram4j.instagram4j.models.user.User;
711
import 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;
815
import com.github.instagram4j.instagram4j.requests.friendships.FriendshipsActionRequest;
16+
import com.github.instagram4j.instagram4j.requests.media.MediaInfoRequest;
917
import com.github.instagram4j.instagram4j.responses.IGResponse;
18+
import com.github.instagram4j.instagram4j.responses.feed.FeedTimelineResponse;
1019
import 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+
1126
import java.io.File;
1227
import java.io.FileInputStream;
1328
import java.io.IOException;
1429
import java.util.ArrayList;
30+
import java.util.Collection;
31+
import java.util.Collections;
1532
import java.util.List;
33+
import java.util.Objects;
1634
import java.util.concurrent.CompletableFuture;
1735
import java.util.concurrent.CompletionException;
1836
import java.util.concurrent.ExecutionException;
37+
import java.util.concurrent.atomic.AtomicInteger;
1938
import java.util.function.Consumer;
2039
import java.util.function.Function;
40+
import java.util.function.Predicate;
41+
import java.util.stream.Collectors;
2142

2243
class 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
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.xcoder.easyinsta.exceptions;
2+
3+
public class IGLoginException extends Exception {
4+
private final Reasons reason;
5+
6+
public IGLoginException(String message, Reasons reason) {
7+
super(message);
8+
this.reason = reason;
9+
}
10+
11+
public Reasons getReason() {
12+
return reason;
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.xcoder.easyinsta.exceptions;
2+
3+
public class InstagramException extends RuntimeException {
4+
private final Reasons reason;
5+
6+
public InstagramException(String message, Reasons reason) {
7+
super(message);
8+
this.reason = reason;
9+
}
10+
11+
public Reasons getReason() {
12+
return reason;
13+
}
14+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.xcoder.easyinsta.exceptions;
2+
3+
public enum Reasons {
4+
REQUIRE_2_FACTOR_AUTHENTICATION,
5+
LOGIN_ERROR_UNKNOWN,
6+
BIO_LENGTH_EXCEEDED,
7+
UNSUPPORTED_FILE_FORMAT,
8+
INVALID_CREDENTIALS,
9+
CHALLENGE_REQUIRED,
10+
CACHING_ERROR,
11+
PROXY_ERROR,
12+
NO_SUCH_ADMIN,
13+
INVALID_USERNAME,
14+
LOGIN_TOO_FREQUENTLY,
15+
API_RESPONSE_ERROR,
16+
NO_SUCH_MESSAGE
17+
18+
}

build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ buildscript {
33
repositories {
44
google()
55
mavenCentral()
6+
gradlePluginPortal()
67
}
78
dependencies {
9+
classpath 'com.google.gms:google-services:4.3.10'
810
classpath 'com.android.tools.build:gradle:4.2.2'
11+
classpath 'gradle.plugin.com.onesignal:onesignal-gradle-plugin:0.14.0'
912
// NOTE: Do not place your application dependencies here; they belong
1013
// in the individual module build.gradle files
1114
}

0 commit comments

Comments
 (0)