mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-26 08:37:29 +00:00
api refactor
This commit is contained in:
parent
4d6ac5d293
commit
49f41f4654
@ -6,22 +6,22 @@ import awais.instagrabber.customviews.helpers.PostFetcher;
|
|||||||
import awais.instagrabber.interfaces.FetchListener;
|
import awais.instagrabber.interfaces.FetchListener;
|
||||||
import awais.instagrabber.models.FeedModel;
|
import awais.instagrabber.models.FeedModel;
|
||||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||||
import awais.instagrabber.webservices.FeedService;
|
import awais.instagrabber.webservices.GraphQLService;
|
||||||
import awais.instagrabber.webservices.ServiceCallback;
|
import awais.instagrabber.webservices.ServiceCallback;
|
||||||
|
|
||||||
public class FeedPostFetchService implements PostFetcher.PostFetchService {
|
public class FeedPostFetchService implements PostFetcher.PostFetchService {
|
||||||
private static final String TAG = "FeedPostFetchService";
|
private static final String TAG = "FeedPostFetchService";
|
||||||
private final FeedService feedService;
|
private final GraphQLService graphQLService;
|
||||||
private String nextCursor;
|
private String nextCursor;
|
||||||
private boolean hasNextPage;
|
private boolean hasNextPage;
|
||||||
|
|
||||||
public FeedPostFetchService() {
|
public FeedPostFetchService() {
|
||||||
feedService = FeedService.getInstance();
|
graphQLService = GraphQLService.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fetch(final FetchListener<List<FeedModel>> fetchListener) {
|
public void fetch(final FetchListener<List<FeedModel>> fetchListener) {
|
||||||
feedService.fetch(25, nextCursor, new ServiceCallback<PostsFetchResponse>() {
|
graphQLService.fetchFeed(25, nextCursor, new ServiceCallback<PostsFetchResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final PostsFetchResponse result) {
|
public void onSuccess(final PostsFetchResponse result) {
|
||||||
if (result == null) return;
|
if (result == null) return;
|
||||||
|
@ -6,12 +6,14 @@ import awais.instagrabber.customviews.helpers.PostFetcher;
|
|||||||
import awais.instagrabber.interfaces.FetchListener;
|
import awais.instagrabber.interfaces.FetchListener;
|
||||||
import awais.instagrabber.models.FeedModel;
|
import awais.instagrabber.models.FeedModel;
|
||||||
import awais.instagrabber.models.HashtagModel;
|
import awais.instagrabber.models.HashtagModel;
|
||||||
|
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||||
|
import awais.instagrabber.webservices.GraphQLService;
|
||||||
import awais.instagrabber.webservices.ServiceCallback;
|
import awais.instagrabber.webservices.ServiceCallback;
|
||||||
import awais.instagrabber.webservices.TagsService;
|
import awais.instagrabber.webservices.TagsService;
|
||||||
import awais.instagrabber.webservices.TagsService.TagPostsFetchResponse;
|
|
||||||
|
|
||||||
public class HashtagPostFetchService implements PostFetcher.PostFetchService {
|
public class HashtagPostFetchService implements PostFetcher.PostFetchService {
|
||||||
private final TagsService tagsService;
|
private final TagsService tagsService;
|
||||||
|
private final GraphQLService graphQLService;
|
||||||
private final HashtagModel hashtagModel;
|
private final HashtagModel hashtagModel;
|
||||||
private String nextMaxId;
|
private String nextMaxId;
|
||||||
private boolean moreAvailable;
|
private boolean moreAvailable;
|
||||||
@ -20,19 +22,20 @@ public class HashtagPostFetchService implements PostFetcher.PostFetchService {
|
|||||||
public HashtagPostFetchService(final HashtagModel hashtagModel, final boolean isLoggedIn) {
|
public HashtagPostFetchService(final HashtagModel hashtagModel, final boolean isLoggedIn) {
|
||||||
this.hashtagModel = hashtagModel;
|
this.hashtagModel = hashtagModel;
|
||||||
this.isLoggedIn = isLoggedIn;
|
this.isLoggedIn = isLoggedIn;
|
||||||
tagsService = TagsService.getInstance();
|
tagsService = isLoggedIn ? TagsService.getInstance() : null;
|
||||||
|
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fetch(final FetchListener<List<FeedModel>> fetchListener) {
|
public void fetch(final FetchListener<List<FeedModel>> fetchListener) {
|
||||||
final ServiceCallback cb = new ServiceCallback<TagPostsFetchResponse>() {
|
final ServiceCallback cb = new ServiceCallback<PostsFetchResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final TagPostsFetchResponse result) {
|
public void onSuccess(final PostsFetchResponse result) {
|
||||||
if (result == null) return;
|
if (result == null) return;
|
||||||
nextMaxId = result.getNextMaxId();
|
nextMaxId = result.getNextCursor();
|
||||||
moreAvailable = result.isMoreAvailable();
|
moreAvailable = result.hasNextPage();
|
||||||
if (fetchListener != null) {
|
if (fetchListener != null) {
|
||||||
fetchListener.onResult(result.getItems());
|
fetchListener.onResult(result.getFeedModels());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +48,7 @@ public class HashtagPostFetchService implements PostFetcher.PostFetchService {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (isLoggedIn) tagsService.fetchPosts(hashtagModel.getName().toLowerCase(), nextMaxId, cb);
|
if (isLoggedIn) tagsService.fetchPosts(hashtagModel.getName().toLowerCase(), nextMaxId, cb);
|
||||||
else tagsService.fetchGraphQLPosts(hashtagModel.getName().toLowerCase(), nextMaxId, cb);
|
else graphQLService.fetchHashtagPosts(hashtagModel.getName().toLowerCase(), nextMaxId, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
package awais.instagrabber.asyncs;
|
|
||||||
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import awais.instagrabber.BuildConfig;
|
|
||||||
import awais.instagrabber.interfaces.FetchListener;
|
|
||||||
import awais.instagrabber.models.HighlightModel;
|
|
||||||
import awais.instagrabber.utils.Constants;
|
|
||||||
import awais.instagrabber.utils.NetworkUtils;
|
|
||||||
|
|
||||||
public final class HighlightsFetcher extends AsyncTask<Void, Void, List<HighlightModel>> {
|
|
||||||
private final String id;
|
|
||||||
private final FetchListener<List<HighlightModel>> fetchListener;
|
|
||||||
|
|
||||||
public HighlightsFetcher(final String id, final FetchListener<List<HighlightModel>> fetchListener) {
|
|
||||||
this.id = id;
|
|
||||||
this.fetchListener = fetchListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<HighlightModel> doInBackground(final Void... voids) {
|
|
||||||
List<HighlightModel> result = null;
|
|
||||||
String url = "https://i.instagram.com/api/v1/highlights/" + id + "/highlights_tray/";
|
|
||||||
|
|
||||||
try {
|
|
||||||
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
|
||||||
conn.setInstanceFollowRedirects(false);
|
|
||||||
conn.setUseCaches(false);
|
|
||||||
conn.setRequestProperty("User-Agent", Constants.I_USER_AGENT);
|
|
||||||
conn.connect();
|
|
||||||
|
|
||||||
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
|
||||||
final JSONArray highlightsReel = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONArray("tray");
|
|
||||||
|
|
||||||
final int length = highlightsReel.length();
|
|
||||||
final List<HighlightModel> highlightModels = new ArrayList<>();
|
|
||||||
// final String[] highlightIds = new String[length];
|
|
||||||
for (int i = 0; i < length; ++i) {
|
|
||||||
final JSONObject highlightNode = highlightsReel.getJSONObject(i);
|
|
||||||
highlightModels.add(new HighlightModel(
|
|
||||||
highlightNode.getString("title"),
|
|
||||||
highlightNode.getString(Constants.EXTRAS_ID),
|
|
||||||
highlightNode.getJSONObject("cover_media")
|
|
||||||
.getJSONObject("cropped_image_version")
|
|
||||||
.getString("url")
|
|
||||||
));
|
|
||||||
}
|
|
||||||
conn.disconnect();
|
|
||||||
result = highlightModels;
|
|
||||||
}
|
|
||||||
|
|
||||||
conn.disconnect();
|
|
||||||
} catch (Exception e) {
|
|
||||||
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(final List<HighlightModel> result) {
|
|
||||||
if (fetchListener != null) fetchListener.onResult(result);
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,12 +6,14 @@ import awais.instagrabber.customviews.helpers.PostFetcher;
|
|||||||
import awais.instagrabber.interfaces.FetchListener;
|
import awais.instagrabber.interfaces.FetchListener;
|
||||||
import awais.instagrabber.models.FeedModel;
|
import awais.instagrabber.models.FeedModel;
|
||||||
import awais.instagrabber.models.LocationModel;
|
import awais.instagrabber.models.LocationModel;
|
||||||
|
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||||
|
import awais.instagrabber.webservices.GraphQLService;
|
||||||
import awais.instagrabber.webservices.LocationService;
|
import awais.instagrabber.webservices.LocationService;
|
||||||
import awais.instagrabber.webservices.LocationService.LocationPostsFetchResponse;
|
|
||||||
import awais.instagrabber.webservices.ServiceCallback;
|
import awais.instagrabber.webservices.ServiceCallback;
|
||||||
|
|
||||||
public class LocationPostFetchService implements PostFetcher.PostFetchService {
|
public class LocationPostFetchService implements PostFetcher.PostFetchService {
|
||||||
private final LocationService locationService;
|
private final LocationService locationService;
|
||||||
|
private final GraphQLService graphQLService;
|
||||||
private final LocationModel locationModel;
|
private final LocationModel locationModel;
|
||||||
private String nextMaxId;
|
private String nextMaxId;
|
||||||
private boolean moreAvailable;
|
private boolean moreAvailable;
|
||||||
@ -20,19 +22,20 @@ public class LocationPostFetchService implements PostFetcher.PostFetchService {
|
|||||||
public LocationPostFetchService(final LocationModel locationModel, final boolean isLoggedIn) {
|
public LocationPostFetchService(final LocationModel locationModel, final boolean isLoggedIn) {
|
||||||
this.locationModel = locationModel;
|
this.locationModel = locationModel;
|
||||||
this.isLoggedIn = isLoggedIn;
|
this.isLoggedIn = isLoggedIn;
|
||||||
locationService = LocationService.getInstance();
|
locationService = isLoggedIn ? LocationService.getInstance() : null;
|
||||||
|
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fetch(final FetchListener<List<FeedModel>> fetchListener) {
|
public void fetch(final FetchListener<List<FeedModel>> fetchListener) {
|
||||||
final ServiceCallback cb = new ServiceCallback<LocationPostsFetchResponse>() {
|
final ServiceCallback cb = new ServiceCallback<PostsFetchResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final LocationPostsFetchResponse result) {
|
public void onSuccess(final PostsFetchResponse result) {
|
||||||
if (result == null) return;
|
if (result == null) return;
|
||||||
nextMaxId = result.getNextMaxId();
|
nextMaxId = result.getNextCursor();
|
||||||
moreAvailable = result.isMoreAvailable();
|
moreAvailable = result.hasNextPage();
|
||||||
if (fetchListener != null) {
|
if (fetchListener != null) {
|
||||||
fetchListener.onResult(result.getItems());
|
fetchListener.onResult(result.getFeedModels());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +48,7 @@ public class LocationPostFetchService implements PostFetcher.PostFetchService {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (isLoggedIn) locationService.fetchPosts(locationModel.getId(), nextMaxId, cb);
|
if (isLoggedIn) locationService.fetchPosts(locationModel.getId(), nextMaxId, cb);
|
||||||
else locationService.fetchGraphQLPosts(locationModel.getId(), nextMaxId, cb);
|
else graphQLService.fetchLocationPosts(locationModel.getId(), nextMaxId, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -7,29 +7,34 @@ import awais.instagrabber.interfaces.FetchListener;
|
|||||||
import awais.instagrabber.models.FeedModel;
|
import awais.instagrabber.models.FeedModel;
|
||||||
import awais.instagrabber.models.ProfileModel;
|
import awais.instagrabber.models.ProfileModel;
|
||||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||||
|
import awais.instagrabber.webservices.GraphQLService;
|
||||||
import awais.instagrabber.webservices.ProfileService;
|
import awais.instagrabber.webservices.ProfileService;
|
||||||
import awais.instagrabber.webservices.ServiceCallback;
|
import awais.instagrabber.webservices.ServiceCallback;
|
||||||
|
|
||||||
public class ProfilePostFetchService implements PostFetcher.PostFetchService {
|
public class ProfilePostFetchService implements PostFetcher.PostFetchService {
|
||||||
private static final String TAG = "ProfilePostFetchService";
|
private static final String TAG = "ProfilePostFetchService";
|
||||||
private final ProfileService profileService;
|
private final ProfileService profileService;
|
||||||
|
private final GraphQLService graphQLService;
|
||||||
private final ProfileModel profileModel;
|
private final ProfileModel profileModel;
|
||||||
private String nextCursor;
|
private final boolean isLoggedIn;
|
||||||
private boolean hasNextPage;
|
private String nextMaxId;
|
||||||
|
private boolean moreAvailable;
|
||||||
|
|
||||||
public ProfilePostFetchService(final ProfileModel profileModel) {
|
public ProfilePostFetchService(final ProfileModel profileModel, final boolean isLoggedIn) {
|
||||||
this.profileModel = profileModel;
|
this.profileModel = profileModel;
|
||||||
profileService = ProfileService.getInstance();
|
this.isLoggedIn = isLoggedIn;
|
||||||
|
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
|
||||||
|
profileService = isLoggedIn ? ProfileService.getInstance() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fetch(final FetchListener<List<FeedModel>> fetchListener) {
|
public void fetch(final FetchListener<List<FeedModel>> fetchListener) {
|
||||||
profileService.fetchPosts(profileModel, 30, nextCursor, new ServiceCallback<PostsFetchResponse>() {
|
final ServiceCallback cb = new ServiceCallback<PostsFetchResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final PostsFetchResponse result) {
|
public void onSuccess(final PostsFetchResponse result) {
|
||||||
if (result == null) return;
|
if (result == null) return;
|
||||||
nextCursor = result.getNextCursor();
|
nextMaxId = result.getNextCursor();
|
||||||
hasNextPage = result.hasNextPage();
|
moreAvailable = result.hasNextPage();
|
||||||
if (fetchListener != null) {
|
if (fetchListener != null) {
|
||||||
fetchListener.onResult(result.getFeedModels());
|
fetchListener.onResult(result.getFeedModels());
|
||||||
}
|
}
|
||||||
@ -42,16 +47,18 @@ public class ProfilePostFetchService implements PostFetcher.PostFetchService {
|
|||||||
fetchListener.onFailure(t);
|
fetchListener.onFailure(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
if (isLoggedIn) profileService.fetchPosts(profileModel.getId(), nextMaxId, cb);
|
||||||
|
else graphQLService.fetchProfilePosts(profileModel.getId(), 30, nextMaxId, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
nextCursor = null;
|
nextMaxId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNextPage() {
|
public boolean hasNextPage() {
|
||||||
return hasNextPage;
|
return moreAvailable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,34 +6,39 @@ import awais.instagrabber.customviews.helpers.PostFetcher;
|
|||||||
import awais.instagrabber.interfaces.FetchListener;
|
import awais.instagrabber.interfaces.FetchListener;
|
||||||
import awais.instagrabber.models.FeedModel;
|
import awais.instagrabber.models.FeedModel;
|
||||||
import awais.instagrabber.models.enums.PostItemType;
|
import awais.instagrabber.models.enums.PostItemType;
|
||||||
|
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||||
|
import awais.instagrabber.webservices.GraphQLService;
|
||||||
import awais.instagrabber.webservices.ProfileService;
|
import awais.instagrabber.webservices.ProfileService;
|
||||||
import awais.instagrabber.webservices.ProfileService.SavedPostsFetchResponse;
|
|
||||||
import awais.instagrabber.webservices.ServiceCallback;
|
import awais.instagrabber.webservices.ServiceCallback;
|
||||||
|
|
||||||
public class SavedPostFetchService implements PostFetcher.PostFetchService {
|
public class SavedPostFetchService implements PostFetcher.PostFetchService {
|
||||||
private final ProfileService profileService;
|
private final ProfileService profileService;
|
||||||
|
private final GraphQLService graphQLService;
|
||||||
private final String profileId;
|
private final String profileId;
|
||||||
private final PostItemType type;
|
private final PostItemType type;
|
||||||
|
private final boolean isLoggedIn;
|
||||||
|
|
||||||
private String nextMaxId;
|
private String nextMaxId;
|
||||||
private boolean moreAvailable;
|
private boolean moreAvailable;
|
||||||
|
|
||||||
public SavedPostFetchService(final String profileId, final PostItemType type) {
|
public SavedPostFetchService(final String profileId, final PostItemType type, final boolean isLoggedIn) {
|
||||||
this.profileId = profileId;
|
this.profileId = profileId;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
profileService = ProfileService.getInstance();
|
this.isLoggedIn = isLoggedIn;
|
||||||
|
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
|
||||||
|
profileService = isLoggedIn ? ProfileService.getInstance() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fetch(final FetchListener<List<FeedModel>> fetchListener) {
|
public void fetch(final FetchListener<List<FeedModel>> fetchListener) {
|
||||||
final ServiceCallback<SavedPostsFetchResponse> callback = new ServiceCallback<SavedPostsFetchResponse>() {
|
final ServiceCallback<PostsFetchResponse> callback = new ServiceCallback<PostsFetchResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final SavedPostsFetchResponse result) {
|
public void onSuccess(final PostsFetchResponse result) {
|
||||||
if (result == null) return;
|
if (result == null) return;
|
||||||
nextMaxId = result.getNextMaxId();
|
nextMaxId = result.getNextCursor();
|
||||||
moreAvailable = result.isMoreAvailable();
|
moreAvailable = result.hasNextPage();
|
||||||
if (fetchListener != null) {
|
if (fetchListener != null) {
|
||||||
fetchListener.onResult(result.getItems());
|
fetchListener.onResult(result.getFeedModels());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +55,8 @@ public class SavedPostFetchService implements PostFetcher.PostFetchService {
|
|||||||
profileService.fetchLiked(nextMaxId, callback);
|
profileService.fetchLiked(nextMaxId, callback);
|
||||||
break;
|
break;
|
||||||
case TAGGED:
|
case TAGGED:
|
||||||
profileService.fetchTagged(profileId, 30, nextMaxId, callback);
|
if (isLoggedIn) profileService.fetchTagged(profileId, nextMaxId, callback);
|
||||||
|
else graphQLService.fetchTaggedPosts(profileId, 30, nextMaxId, callback);
|
||||||
break;
|
break;
|
||||||
case SAVED:
|
case SAVED:
|
||||||
default:
|
default:
|
||||||
|
@ -40,24 +40,26 @@ import awais.instagrabber.models.FeedModel;
|
|||||||
import awais.instagrabber.models.PostsLayoutPreferences;
|
import awais.instagrabber.models.PostsLayoutPreferences;
|
||||||
import awais.instagrabber.models.enums.PostItemType;
|
import awais.instagrabber.models.enums.PostItemType;
|
||||||
import awais.instagrabber.utils.Constants;
|
import awais.instagrabber.utils.Constants;
|
||||||
|
import awais.instagrabber.utils.CookieUtils;
|
||||||
import awais.instagrabber.utils.DownloadUtils;
|
import awais.instagrabber.utils.DownloadUtils;
|
||||||
|
import awais.instagrabber.utils.TextUtils;
|
||||||
import awais.instagrabber.utils.Utils;
|
import awais.instagrabber.utils.Utils;
|
||||||
|
|
||||||
import static androidx.core.content.PermissionChecker.checkSelfPermission;
|
import static androidx.core.content.PermissionChecker.checkSelfPermission;
|
||||||
import static awais.instagrabber.utils.DownloadUtils.WRITE_PERMISSION;
|
import static awais.instagrabber.utils.DownloadUtils.WRITE_PERMISSION;
|
||||||
|
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||||
|
|
||||||
public final class SavedViewerFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
|
public final class SavedViewerFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
|
||||||
private static final int STORAGE_PERM_REQUEST_CODE = 8020;
|
private static final int STORAGE_PERM_REQUEST_CODE = 8020;
|
||||||
private static final int STORAGE_PERM_REQUEST_CODE_FOR_SELECTION = 8030;
|
private static final int STORAGE_PERM_REQUEST_CODE_FOR_SELECTION = 8030;
|
||||||
|
|
||||||
private FragmentSavedBinding binding;
|
private FragmentSavedBinding binding;
|
||||||
private String username;
|
private String username, cookie, profileId;
|
||||||
private ActionMode actionMode;
|
private ActionMode actionMode;
|
||||||
private SwipeRefreshLayout root;
|
private SwipeRefreshLayout root;
|
||||||
private AppCompatActivity fragmentActivity;
|
private AppCompatActivity fragmentActivity;
|
||||||
private boolean shouldRefresh = true;
|
private boolean isLoggedIn, shouldRefresh = true;
|
||||||
private PostItemType type;
|
private PostItemType type;
|
||||||
private String profileId;
|
|
||||||
private Set<FeedModel> selectedFeedModels;
|
private Set<FeedModel> selectedFeedModels;
|
||||||
private FeedModel downloadFeedModel;
|
private FeedModel downloadFeedModel;
|
||||||
private int downloadChildPosition = -1;
|
private int downloadChildPosition = -1;
|
||||||
@ -225,6 +227,8 @@ public final class SavedViewerFragment extends Fragment implements SwipeRefreshL
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
|
public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
|
||||||
|
cookie = settingsHelper.getString(Constants.COOKIE);
|
||||||
|
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) != null;
|
||||||
if (root != null) {
|
if (root != null) {
|
||||||
shouldRefresh = false;
|
shouldRefresh = false;
|
||||||
return root;
|
return root;
|
||||||
@ -281,7 +285,7 @@ public final class SavedViewerFragment extends Fragment implements SwipeRefreshL
|
|||||||
private void setupPosts() {
|
private void setupPosts() {
|
||||||
binding.posts.setViewModelStoreOwner(this)
|
binding.posts.setViewModelStoreOwner(this)
|
||||||
.setLifeCycleOwner(this)
|
.setLifeCycleOwner(this)
|
||||||
.setPostFetchService(new SavedPostFetchService(profileId, type))
|
.setPostFetchService(new SavedPostFetchService(profileId, type, isLoggedIn))
|
||||||
.setLayoutPreferences(layoutPreferences)
|
.setLayoutPreferences(layoutPreferences)
|
||||||
.addFetchStatusChangeListener(fetching -> updateSwipeRefreshState())
|
.addFetchStatusChangeListener(fetching -> updateSwipeRefreshState())
|
||||||
.setFeedItemCallback(feedItemCallback)
|
.setFeedItemCallback(feedItemCallback)
|
||||||
|
@ -54,7 +54,6 @@ import awais.instagrabber.R;
|
|||||||
import awais.instagrabber.activities.MainActivity;
|
import awais.instagrabber.activities.MainActivity;
|
||||||
import awais.instagrabber.adapters.FeedAdapterV2;
|
import awais.instagrabber.adapters.FeedAdapterV2;
|
||||||
import awais.instagrabber.adapters.HighlightsAdapter;
|
import awais.instagrabber.adapters.HighlightsAdapter;
|
||||||
import awais.instagrabber.asyncs.HighlightsFetcher;
|
|
||||||
import awais.instagrabber.asyncs.ProfileFetcher;
|
import awais.instagrabber.asyncs.ProfileFetcher;
|
||||||
import awais.instagrabber.asyncs.ProfilePostFetchService;
|
import awais.instagrabber.asyncs.ProfilePostFetchService;
|
||||||
import awais.instagrabber.asyncs.UsernameFetcher;
|
import awais.instagrabber.asyncs.UsernameFetcher;
|
||||||
@ -75,6 +74,7 @@ import awais.instagrabber.dialogs.ProfilePicDialogFragment;
|
|||||||
import awais.instagrabber.fragments.PostViewV2Fragment;
|
import awais.instagrabber.fragments.PostViewV2Fragment;
|
||||||
import awais.instagrabber.interfaces.FetchListener;
|
import awais.instagrabber.interfaces.FetchListener;
|
||||||
import awais.instagrabber.models.FeedModel;
|
import awais.instagrabber.models.FeedModel;
|
||||||
|
import awais.instagrabber.models.HighlightModel;
|
||||||
import awais.instagrabber.models.PostsLayoutPreferences;
|
import awais.instagrabber.models.PostsLayoutPreferences;
|
||||||
import awais.instagrabber.models.ProfileModel;
|
import awais.instagrabber.models.ProfileModel;
|
||||||
import awais.instagrabber.models.StoryModel;
|
import awais.instagrabber.models.StoryModel;
|
||||||
@ -729,6 +729,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setupButtons(final String profileId, final String myId) {
|
private void setupButtons(final String profileId, final String myId) {
|
||||||
|
profileDetailsBinding.btnTagged.setVisibility(profileModel.isReallyPrivate() ? View.GONE : View.VISIBLE);
|
||||||
if (isLoggedIn) {
|
if (isLoggedIn) {
|
||||||
if (profileId.equals(myId)) {
|
if (profileId.equals(myId)) {
|
||||||
profileDetailsBinding.btnTagged.setVisibility(View.VISIBLE);
|
profileDetailsBinding.btnTagged.setVisibility(View.VISIBLE);
|
||||||
@ -738,7 +739,6 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
profileDetailsBinding.btnSaved.setText(R.string.saved);
|
profileDetailsBinding.btnSaved.setText(R.string.saved);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
profileDetailsBinding.btnTagged.setVisibility(View.GONE);
|
|
||||||
profileDetailsBinding.btnSaved.setVisibility(View.GONE);
|
profileDetailsBinding.btnSaved.setVisibility(View.GONE);
|
||||||
profileDetailsBinding.btnLiked.setVisibility(View.GONE);
|
profileDetailsBinding.btnLiked.setVisibility(View.GONE);
|
||||||
profileDetailsBinding.btnDM.setVisibility(View.VISIBLE); // maybe there is a judgment mechanism?
|
profileDetailsBinding.btnDM.setVisibility(View.VISIBLE); // maybe there is a judgment mechanism?
|
||||||
@ -776,7 +776,6 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
restrictMenuItem.setTitle(R.string.restrict);
|
restrictMenuItem.setTitle(R.string.restrict);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
profileDetailsBinding.btnTagged.setVisibility(profileModel.isReallyPrivate() ? View.GONE : View.VISIBLE);
|
|
||||||
if (blockMenuItem != null) {
|
if (blockMenuItem != null) {
|
||||||
blockMenuItem.setVisible(true);
|
blockMenuItem.setVisible(true);
|
||||||
if (profileModel.isBlocked()) {
|
if (profileModel.isBlocked()) {
|
||||||
@ -817,14 +816,24 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
Log.e(TAG, "Error", t);
|
Log.e(TAG, "Error", t);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
new HighlightsFetcher(profileId,
|
storiesService.fetchHighlights(profileId,
|
||||||
result -> {
|
new ServiceCallback<List<HighlightModel>>() {
|
||||||
highlightsFetching = false;
|
@Override
|
||||||
if (result != null) {
|
public void onSuccess(final List<HighlightModel> result) {
|
||||||
profileDetailsBinding.highlightsList.setVisibility(View.VISIBLE);
|
highlightsFetching = false;
|
||||||
highlightsViewModel.getList().postValue(result);
|
if (result != null) {
|
||||||
} else profileDetailsBinding.highlightsList.setVisibility(View.GONE);
|
profileDetailsBinding.highlightsList.setVisibility(View.VISIBLE);
|
||||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
highlightsViewModel.getList().postValue(result);
|
||||||
|
}
|
||||||
|
else profileDetailsBinding.highlightsList.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(final Throwable t) {
|
||||||
|
profileDetailsBinding.highlightsList.setVisibility(View.GONE);
|
||||||
|
Log.e(TAG, "Error", t);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupCommonListeners() {
|
private void setupCommonListeners() {
|
||||||
@ -979,7 +988,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
|||||||
private void setupPosts() {
|
private void setupPosts() {
|
||||||
binding.postsRecyclerView.setViewModelStoreOwner(this)
|
binding.postsRecyclerView.setViewModelStoreOwner(this)
|
||||||
.setLifeCycleOwner(this)
|
.setLifeCycleOwner(this)
|
||||||
.setPostFetchService(new ProfilePostFetchService(profileModel))
|
.setPostFetchService(new ProfilePostFetchService(profileModel, isLoggedIn))
|
||||||
.setLayoutPreferences(layoutPreferences)
|
.setLayoutPreferences(layoutPreferences)
|
||||||
.addFetchStatusChangeListener(fetching -> updateSwipeRefreshState())
|
.addFetchStatusChangeListener(fetching -> updateSwipeRefreshState())
|
||||||
.setFeedItemCallback(feedItemCallback)
|
.setFeedItemCallback(feedItemCallback)
|
||||||
|
@ -6,7 +6,7 @@ import retrofit2.Call;
|
|||||||
import retrofit2.http.GET;
|
import retrofit2.http.GET;
|
||||||
import retrofit2.http.QueryMap;
|
import retrofit2.http.QueryMap;
|
||||||
|
|
||||||
public interface FeedRepository {
|
public interface GraphQLRepository {
|
||||||
@GET("/graphql/query/")
|
@GET("/graphql/query/")
|
||||||
Call<String> fetch(@QueryMap(encoded = true) Map<String, String> queryParams);
|
Call<String> fetch(@QueryMap(encoded = true) Map<String, String> queryParams);
|
||||||
}
|
}
|
@ -12,7 +12,4 @@ public interface LocationRepository {
|
|||||||
@GET("/api/v1/feed/location/{location}/")
|
@GET("/api/v1/feed/location/{location}/")
|
||||||
Call<String> fetchPosts(@Path("location") final String locationId,
|
Call<String> fetchPosts(@Path("location") final String locationId,
|
||||||
@QueryMap Map<String, String> queryParams);
|
@QueryMap Map<String, String> queryParams);
|
||||||
|
|
||||||
@GET("/graphql/query/")
|
|
||||||
Call<String> fetchGraphQLPosts(@QueryMap(encoded = true) Map<String, String> queryParams);
|
|
||||||
}
|
}
|
||||||
|
@ -9,15 +9,18 @@ import retrofit2.http.QueryMap;
|
|||||||
|
|
||||||
public interface ProfileRepository {
|
public interface ProfileRepository {
|
||||||
|
|
||||||
@GET("api/v1/users/{uid}/info/")
|
@GET("/api/v1/users/{uid}/info/")
|
||||||
Call<String> getUserInfo(@Path("uid") final String uid);
|
Call<String> getUserInfo(@Path("uid") final String uid);
|
||||||
|
|
||||||
@GET("/graphql/query/")
|
@GET("/api/v1/feed/user/{uid}/")
|
||||||
Call<String> fetch(@QueryMap Map<String, String> queryMap);
|
Call<String> fetch(@Path("uid") final String uid, @QueryMap Map<String, String> queryParams);
|
||||||
|
|
||||||
@GET("/api/v1/feed/saved/")
|
@GET("/api/v1/feed/saved/")
|
||||||
Call<String> fetchSaved(@QueryMap Map<String, String> queryParams);
|
Call<String> fetchSaved(@QueryMap Map<String, String> queryParams);
|
||||||
|
|
||||||
@GET("/api/v1/feed/liked/")
|
@GET("/api/v1/feed/liked/")
|
||||||
Call<String> fetchLiked(@QueryMap Map<String, String> queryParams);
|
Call<String> fetchLiked(@QueryMap Map<String, String> queryParams);
|
||||||
|
|
||||||
|
@GET("/api/v1/usertags/{profileId}/feed/")
|
||||||
|
Call<String> fetchTagged(@Path("profileId") final String profileId, @QueryMap Map<String, String> queryParams);
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,11 @@ public interface StoriesRepository {
|
|||||||
|
|
||||||
@FormUrlEncoded
|
@FormUrlEncoded
|
||||||
@POST("/api/v1/feed/reels_tray/")
|
@POST("/api/v1/feed/reels_tray/")
|
||||||
Call<String> getStories(@Header("User-Agent") String userAgent,
|
Call<String> getFeedStories(@Header("User-Agent") String userAgent,
|
||||||
@FieldMap Map<String, String> form);
|
@FieldMap Map<String, String> form);
|
||||||
|
|
||||||
|
@GET("/api/v1/highlights/{uid}/highlights_tray/")
|
||||||
|
Call<String> fetchHighlights(@Path("uid") final String uid);
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
Call<String> getUserStory(@Header("User-Agent") String userAgent, @Url String url);
|
Call<String> getUserStory(@Header("User-Agent") String userAgent, @Url String url);
|
||||||
|
@ -24,7 +24,4 @@ public interface TagsRepository {
|
|||||||
@GET("/api/v1/feed/tag/{tag}/")
|
@GET("/api/v1/feed/tag/{tag}/")
|
||||||
Call<String> fetchPosts(@Path("tag") final String tag,
|
Call<String> fetchPosts(@Path("tag") final String tag,
|
||||||
@QueryMap Map<String, String> queryParams);
|
@QueryMap Map<String, String> queryParams);
|
||||||
|
|
||||||
@GET("/graphql/query/")
|
|
||||||
Call<String> fetchGraphQLPosts(@QueryMap(encoded = true) Map<String, String> queryParams);
|
|
||||||
}
|
}
|
||||||
|
@ -21,10 +21,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import awais.instagrabber.models.FeedModel;
|
import awais.instagrabber.models.FeedModel;
|
||||||
import awais.instagrabber.models.PostChild;
|
import awais.instagrabber.repositories.GraphQLRepository;
|
||||||
import awais.instagrabber.models.ProfileModel;
|
|
||||||
import awais.instagrabber.models.enums.MediaItemType;
|
|
||||||
import awais.instagrabber.repositories.FeedRepository;
|
|
||||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||||
import awais.instagrabber.utils.Constants;
|
import awais.instagrabber.utils.Constants;
|
||||||
import awais.instagrabber.utils.ResponseBodyUtils;
|
import awais.instagrabber.utils.ResponseBodyUtils;
|
||||||
@ -34,69 +31,43 @@ import retrofit2.Callback;
|
|||||||
import retrofit2.Response;
|
import retrofit2.Response;
|
||||||
import retrofit2.Retrofit;
|
import retrofit2.Retrofit;
|
||||||
|
|
||||||
public class FeedService extends BaseService {
|
public class GraphQLService extends BaseService {
|
||||||
private static final String TAG = "FeedService";
|
private static final String TAG = "GraphQLService";
|
||||||
private static final boolean loadFromMock = false;
|
private static final boolean loadFromMock = false;
|
||||||
|
|
||||||
private final FeedRepository repository;
|
private final GraphQLRepository repository;
|
||||||
|
|
||||||
private static FeedService instance;
|
private static GraphQLService instance;
|
||||||
|
|
||||||
private FeedService() {
|
private GraphQLService() {
|
||||||
final Retrofit retrofit = getRetrofitBuilder()
|
final Retrofit retrofit = getRetrofitBuilder()
|
||||||
.baseUrl("https://www.instagram.com")
|
.baseUrl("https://www.instagram.com")
|
||||||
.build();
|
.build();
|
||||||
repository = retrofit.create(FeedRepository.class);
|
repository = retrofit.create(GraphQLRepository.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FeedService getInstance() {
|
public static GraphQLService getInstance() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new FeedService();
|
instance = new GraphQLService();
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fetch(final int maxItemsToLoad,
|
private void fetch(final String queryHash,
|
||||||
final String cursor,
|
final String variables,
|
||||||
final ServiceCallback<PostsFetchResponse> callback) {
|
final String arg1,
|
||||||
if (loadFromMock) {
|
final String arg2,
|
||||||
final Handler handler = new Handler();
|
final ServiceCallback<PostsFetchResponse> callback) {
|
||||||
handler.postDelayed(() -> {
|
|
||||||
final ClassLoader classLoader = getClass().getClassLoader();
|
|
||||||
if (classLoader == null) {
|
|
||||||
Log.e(TAG, "fetch: classLoader is null!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try (InputStream resourceAsStream = classLoader.getResourceAsStream("feed_response.json");
|
|
||||||
Reader in = new InputStreamReader(resourceAsStream, StandardCharsets.UTF_8)) {
|
|
||||||
final int bufferSize = 1024;
|
|
||||||
final char[] buffer = new char[bufferSize];
|
|
||||||
final StringBuilder out = new StringBuilder();
|
|
||||||
int charsRead;
|
|
||||||
while ((charsRead = in.read(buffer, 0, buffer.length)) > 0) {
|
|
||||||
out.append(buffer, 0, charsRead);
|
|
||||||
}
|
|
||||||
callback.onSuccess(parseResponseBody(out.toString()));
|
|
||||||
} catch (IOException | JSONException e) {
|
|
||||||
Log.e(TAG, "fetch: ", e);
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final Map<String, String> queryMap = new HashMap<>();
|
final Map<String, String> queryMap = new HashMap<>();
|
||||||
queryMap.put("query_hash", "c699b185975935ae2a457f24075de8c7");
|
queryMap.put("query_hash", queryHash);
|
||||||
queryMap.put("variables", "{" +
|
queryMap.put("variables", variables);
|
||||||
"\"fetch_media_item_count\":" + maxItemsToLoad + "," +
|
|
||||||
"\"fetch_like\":3,\"has_stories\":false,\"has_stories\":false,\"has_threaded_comments\":true," +
|
|
||||||
"\"fetch_media_item_cursor\":\"" + (cursor == null ? "" : cursor) + "\"" +
|
|
||||||
"}");
|
|
||||||
final Call<String> request = repository.fetch(queryMap);
|
final Call<String> request = repository.fetch(queryMap);
|
||||||
request.enqueue(new Callback<String>() {
|
request.enqueue(new Callback<String>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||||
try {
|
try {
|
||||||
// Log.d(TAG, "onResponse: body: " + response.body());
|
// Log.d(TAG, "onResponse: body: " + response.body());
|
||||||
final PostsFetchResponse postsFetchResponse = parseResponse(response);
|
final PostsFetchResponse postsFetchResponse = parsePostResponse(response, arg1, arg2);
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
callback.onSuccess(postsFetchResponse);
|
callback.onSuccess(postsFetchResponse);
|
||||||
}
|
}
|
||||||
@ -115,26 +86,111 @@ public class FeedService extends BaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fetchFeed(final int maxItemsToLoad,
|
||||||
|
final String cursor,
|
||||||
|
final ServiceCallback<PostsFetchResponse> callback) {
|
||||||
|
if (loadFromMock) {
|
||||||
|
final Handler handler = new Handler();
|
||||||
|
handler.postDelayed(() -> {
|
||||||
|
final ClassLoader classLoader = getClass().getClassLoader();
|
||||||
|
if (classLoader == null) {
|
||||||
|
Log.e(TAG, "fetch: classLoader is null!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try (InputStream resourceAsStream = classLoader.getResourceAsStream("feed_response.json");
|
||||||
|
Reader in = new InputStreamReader(resourceAsStream, StandardCharsets.UTF_8)) {
|
||||||
|
final int bufferSize = 1024;
|
||||||
|
final char[] buffer = new char[bufferSize];
|
||||||
|
final StringBuilder out = new StringBuilder();
|
||||||
|
int charsRead;
|
||||||
|
while ((charsRead = in.read(buffer, 0, buffer.length)) > 0) {
|
||||||
|
out.append(buffer, 0, charsRead);
|
||||||
|
}
|
||||||
|
callback.onSuccess(parseResponseBody(out.toString(), Constants.EXTRAS_USER, "edge_web_feed_timeline"));
|
||||||
|
} catch (IOException | JSONException e) {
|
||||||
|
Log.e(TAG, "fetch: ", e);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fetch("c699b185975935ae2a457f24075de8c7",
|
||||||
|
"{\"fetch_media_item_count\":" + maxItemsToLoad + "," +
|
||||||
|
"\"fetch_like\":3,\"has_stories\":false,\"has_stories\":false,\"has_threaded_comments\":true," +
|
||||||
|
"\"fetch_media_item_cursor\":\"" + (cursor == null ? "" : cursor) + "\"}",
|
||||||
|
Constants.EXTRAS_USER,
|
||||||
|
"edge_web_feed_timeline",
|
||||||
|
callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fetchLocationPosts(@NonNull final String locationId,
|
||||||
|
final String maxId,
|
||||||
|
final ServiceCallback<PostsFetchResponse> callback) {
|
||||||
|
fetch("36bd0f2bf5911908de389b8ceaa3be6d",
|
||||||
|
"{\"id\":\"" + locationId + "\"," +
|
||||||
|
"\"first\":25," +
|
||||||
|
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
||||||
|
Constants.EXTRAS_LOCATION,
|
||||||
|
"edge_location_to_media",
|
||||||
|
callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fetchHashtagPosts(@NonNull final String tag,
|
||||||
|
final String maxId,
|
||||||
|
final ServiceCallback<PostsFetchResponse> callback) {
|
||||||
|
fetch("9b498c08113f1e09617a1703c22b2f32",
|
||||||
|
"{\"tag_name\":\"" + tag + "\"," +
|
||||||
|
"\"first\":25," +
|
||||||
|
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
||||||
|
Constants.EXTRAS_HASHTAG,
|
||||||
|
"edge_hashtag_to_media",
|
||||||
|
callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fetchProfilePosts(@NonNull final String profileId,
|
||||||
|
final int postsPerPage,
|
||||||
|
final String maxId,
|
||||||
|
final ServiceCallback<PostsFetchResponse> callback) {
|
||||||
|
fetch("18a7b935ab438c4514b1f742d8fa07a7",
|
||||||
|
"{\"id\":\"" + profileId + "\"," +
|
||||||
|
"\"first\":" + postsPerPage + "," +
|
||||||
|
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
||||||
|
Constants.EXTRAS_USER,
|
||||||
|
"edge_owner_to_timeline_media",
|
||||||
|
callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fetchTaggedPosts(@NonNull final String profileId,
|
||||||
|
final int postsPerPage,
|
||||||
|
final String maxId,
|
||||||
|
final ServiceCallback<PostsFetchResponse> callback) {
|
||||||
|
fetch("31fe64d9463cbbe58319dced405c6206",
|
||||||
|
"{\"id\":\"" + profileId + "\"," +
|
||||||
|
"\"first\":" + postsPerPage + "," +
|
||||||
|
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"}",
|
||||||
|
Constants.EXTRAS_USER,
|
||||||
|
"edge_user_to_photos_of_you",
|
||||||
|
callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private PostsFetchResponse parseResponse(@NonNull final Response<String> response) throws JSONException {
|
private PostsFetchResponse parsePostResponse(@NonNull final Response<String> response, @NonNull final String arg1, @NonNull final String arg2) throws JSONException {
|
||||||
if (TextUtils.isEmpty(response.body())) {
|
if (TextUtils.isEmpty(response.body())) {
|
||||||
Log.e(TAG, "parseResponse: feed response body is empty with status code: " + response.code());
|
Log.e(TAG, "parseResponse: feed response body is empty with status code: " + response.code());
|
||||||
return new PostsFetchResponse(Collections.emptyList(), false, null);
|
return new PostsFetchResponse(Collections.emptyList(), false, null);
|
||||||
}
|
}
|
||||||
return parseResponseBody(response.body());
|
return parseResponseBody(response.body(), arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private PostsFetchResponse parseResponseBody(@NonNull final String body)
|
private PostsFetchResponse parseResponseBody(@NonNull final String body, @NonNull final String arg1, @NonNull final String arg2)
|
||||||
throws JSONException {
|
throws JSONException {
|
||||||
final List<FeedModel> feedModels = new ArrayList<>();
|
final List<FeedModel> feedModels = new ArrayList<>();
|
||||||
final JSONObject timelineFeed = new JSONObject(body)
|
final JSONObject timelineFeed = new JSONObject(body)
|
||||||
.getJSONObject("data")
|
.getJSONObject("data")
|
||||||
.getJSONObject(Constants.EXTRAS_USER)
|
.getJSONObject(arg1)
|
||||||
.getJSONObject("edge_web_feed_timeline");
|
.getJSONObject(arg2);
|
||||||
final String endCursor;
|
final String endCursor;
|
||||||
final boolean hasNextPage;
|
final boolean hasNextPage;
|
||||||
|
|
@ -19,6 +19,7 @@ import java.util.Objects;
|
|||||||
|
|
||||||
import awais.instagrabber.models.FeedModel;
|
import awais.instagrabber.models.FeedModel;
|
||||||
import awais.instagrabber.repositories.LocationRepository;
|
import awais.instagrabber.repositories.LocationRepository;
|
||||||
|
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||||
import awais.instagrabber.utils.ResponseBodyUtils;
|
import awais.instagrabber.utils.ResponseBodyUtils;
|
||||||
import awais.instagrabber.utils.TextUtils;
|
import awais.instagrabber.utils.TextUtils;
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
@ -29,7 +30,7 @@ import retrofit2.Retrofit;
|
|||||||
public class LocationService extends BaseService {
|
public class LocationService extends BaseService {
|
||||||
private static final String TAG = "LocationService";
|
private static final String TAG = "LocationService";
|
||||||
|
|
||||||
private final LocationRepository repository, webRepository;
|
private final LocationRepository repository;
|
||||||
|
|
||||||
private static LocationService instance;
|
private static LocationService instance;
|
||||||
|
|
||||||
@ -38,10 +39,6 @@ public class LocationService extends BaseService {
|
|||||||
.baseUrl("https://i.instagram.com")
|
.baseUrl("https://i.instagram.com")
|
||||||
.build();
|
.build();
|
||||||
repository = retrofit.create(LocationRepository.class);
|
repository = retrofit.create(LocationRepository.class);
|
||||||
final Retrofit webRetrofit = getRetrofitBuilder()
|
|
||||||
.baseUrl("https://www.instagram.com")
|
|
||||||
.build();
|
|
||||||
webRepository = webRetrofit.create(LocationRepository.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LocationService getInstance() {
|
public static LocationService getInstance() {
|
||||||
@ -53,7 +50,7 @@ public class LocationService extends BaseService {
|
|||||||
|
|
||||||
public void fetchPosts(@NonNull final String locationId,
|
public void fetchPosts(@NonNull final String locationId,
|
||||||
final String maxId,
|
final String maxId,
|
||||||
final ServiceCallback<LocationPostsFetchResponse> callback) {
|
final ServiceCallback<PostsFetchResponse> callback) {
|
||||||
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
||||||
if (!TextUtils.isEmpty(maxId)) {
|
if (!TextUtils.isEmpty(maxId)) {
|
||||||
builder.put("max_id", maxId);
|
builder.put("max_id", maxId);
|
||||||
@ -71,7 +68,7 @@ public class LocationService extends BaseService {
|
|||||||
callback.onSuccess(null);
|
callback.onSuccess(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final LocationPostsFetchResponse tagPostsFetchResponse = parseResponse(body);
|
final PostsFetchResponse tagPostsFetchResponse = parseResponse(body);
|
||||||
callback.onSuccess(tagPostsFetchResponse);
|
callback.onSuccess(tagPostsFetchResponse);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.e(TAG, "onResponse", e);
|
Log.e(TAG, "onResponse", e);
|
||||||
@ -88,7 +85,7 @@ public class LocationService extends BaseService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocationPostsFetchResponse parseResponse(@NonNull final String body) throws JSONException {
|
private PostsFetchResponse parseResponse(@NonNull final String body) throws JSONException {
|
||||||
final JSONObject root = new JSONObject(body);
|
final JSONObject root = new JSONObject(body);
|
||||||
final boolean moreAvailable = root.optBoolean("more_available");
|
final boolean moreAvailable = root.optBoolean("more_available");
|
||||||
final String nextMaxId = root.optString("next_max_id");
|
final String nextMaxId = root.optString("next_max_id");
|
||||||
@ -96,12 +93,10 @@ public class LocationService extends BaseService {
|
|||||||
final String status = root.optString("status");
|
final String status = root.optString("status");
|
||||||
final JSONArray itemsJson = root.optJSONArray("items");
|
final JSONArray itemsJson = root.optJSONArray("items");
|
||||||
final List<FeedModel> items = parseItems(itemsJson);
|
final List<FeedModel> items = parseItems(itemsJson);
|
||||||
return new LocationPostsFetchResponse(
|
return new PostsFetchResponse(
|
||||||
|
items,
|
||||||
moreAvailable,
|
moreAvailable,
|
||||||
nextMaxId,
|
nextMaxId
|
||||||
numResults,
|
|
||||||
status,
|
|
||||||
items
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,174 +117,4 @@ public class LocationService extends BaseService {
|
|||||||
}
|
}
|
||||||
return feedModels;
|
return feedModels;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fetchGraphQLPosts(@NonNull final String locationId,
|
|
||||||
final String maxId,
|
|
||||||
final ServiceCallback<LocationPostsFetchResponse> callback) {
|
|
||||||
final Map<String, String> queryMap = new HashMap<>();
|
|
||||||
queryMap.put("query_hash", "36bd0f2bf5911908de389b8ceaa3be6d");
|
|
||||||
queryMap.put("variables", "{" +
|
|
||||||
"\"id\":\"" + locationId + "\"," +
|
|
||||||
"\"first\":25," +
|
|
||||||
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"" +
|
|
||||||
"}");
|
|
||||||
final Call<String> request = webRepository.fetchGraphQLPosts(queryMap);
|
|
||||||
request.enqueue(new Callback<String>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
|
||||||
try {
|
|
||||||
if (callback == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final String body = response.body();
|
|
||||||
if (TextUtils.isEmpty(body)) {
|
|
||||||
callback.onSuccess(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final LocationPostsFetchResponse tagPostsFetchResponse = parseGraphQLResponse(body);
|
|
||||||
callback.onSuccess(tagPostsFetchResponse);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.e(TAG, "onResponse", e);
|
|
||||||
callback.onFailure(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
|
||||||
if (callback != null) {
|
|
||||||
callback.onFailure(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private LocationPostsFetchResponse parseGraphQLResponse(@NonNull final String body) throws JSONException {
|
|
||||||
final JSONObject rootroot = new JSONObject(body);
|
|
||||||
final JSONObject root = rootroot.getJSONObject("data").getJSONObject("location").getJSONObject("edge_location_to_media");
|
|
||||||
final boolean moreAvailable = root.getJSONObject("page_info").optBoolean("has_next_page");
|
|
||||||
final String nextMaxId = root.getJSONObject("page_info").optString("end_cursor");
|
|
||||||
final int numResults = root.optInt("count");
|
|
||||||
final String status = rootroot.optString("status");
|
|
||||||
final JSONArray itemsJson = root.optJSONArray("edges");
|
|
||||||
final List<FeedModel> items = parseGraphQLItems(itemsJson);
|
|
||||||
return new LocationPostsFetchResponse(
|
|
||||||
moreAvailable,
|
|
||||||
nextMaxId,
|
|
||||||
numResults,
|
|
||||||
status,
|
|
||||||
items
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<FeedModel> parseGraphQLItems(final JSONArray items) throws JSONException {
|
|
||||||
if (items == null) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
final List<FeedModel> feedModels = new ArrayList<>();
|
|
||||||
for (int i = 0; i < items.length(); i++) {
|
|
||||||
final JSONObject itemJson = items.optJSONObject(i);
|
|
||||||
if (itemJson == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final FeedModel feedModel = ResponseBodyUtils.parseGraphQLItem(itemJson);
|
|
||||||
if (feedModel != null) {
|
|
||||||
feedModels.add(feedModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return feedModels;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class LocationPostsFetchResponse {
|
|
||||||
private boolean moreAvailable;
|
|
||||||
private String nextMaxId;
|
|
||||||
private int numResults;
|
|
||||||
private String status;
|
|
||||||
private List<FeedModel> items;
|
|
||||||
|
|
||||||
public LocationPostsFetchResponse(final boolean moreAvailable,
|
|
||||||
final String nextMaxId,
|
|
||||||
final int numResults,
|
|
||||||
final String status,
|
|
||||||
final List<FeedModel> items) {
|
|
||||||
this.moreAvailable = moreAvailable;
|
|
||||||
this.nextMaxId = nextMaxId;
|
|
||||||
this.numResults = numResults;
|
|
||||||
this.status = status;
|
|
||||||
this.items = items;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMoreAvailable() {
|
|
||||||
return moreAvailable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocationPostsFetchResponse setMoreAvailable(final boolean moreAvailable) {
|
|
||||||
this.moreAvailable = moreAvailable;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNextMaxId() {
|
|
||||||
return nextMaxId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocationPostsFetchResponse setNextMaxId(final String nextMaxId) {
|
|
||||||
this.nextMaxId = nextMaxId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNumResults() {
|
|
||||||
return numResults;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocationPostsFetchResponse setNumResults(final int numResults) {
|
|
||||||
this.numResults = numResults;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocationPostsFetchResponse setStatus(final String status) {
|
|
||||||
this.status = status;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<FeedModel> getItems() {
|
|
||||||
return items;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocationPostsFetchResponse setItems(final List<FeedModel> items) {
|
|
||||||
this.items = items;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(final Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
final LocationPostsFetchResponse that = (LocationPostsFetchResponse) o;
|
|
||||||
return moreAvailable == that.moreAvailable &&
|
|
||||||
numResults == that.numResults &&
|
|
||||||
Objects.equals(nextMaxId, that.nextMaxId) &&
|
|
||||||
Objects.equals(status, that.status) &&
|
|
||||||
Objects.equals(items, that.items);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(moreAvailable, nextMaxId, numResults, status, items);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "LocationPostsFetchResponse{" +
|
|
||||||
"moreAvailable=" + moreAvailable +
|
|
||||||
", nextMaxId='" + nextMaxId + '\'' +
|
|
||||||
", numResults=" + numResults +
|
|
||||||
", status='" + status + '\'' +
|
|
||||||
", items=" + items +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,15 +12,9 @@ import org.json.JSONObject;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import awais.instagrabber.models.FeedModel;
|
import awais.instagrabber.models.FeedModel;
|
||||||
import awais.instagrabber.models.PostChild;
|
|
||||||
import awais.instagrabber.models.ProfileModel;
|
|
||||||
import awais.instagrabber.models.enums.MediaItemType;
|
|
||||||
import awais.instagrabber.repositories.ProfileRepository;
|
import awais.instagrabber.repositories.ProfileRepository;
|
||||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||||
import awais.instagrabber.repositories.responses.UserInfo;
|
import awais.instagrabber.repositories.responses.UserInfo;
|
||||||
@ -36,7 +30,6 @@ public class ProfileService extends BaseService {
|
|||||||
private static final String TAG = "ProfileService";
|
private static final String TAG = "ProfileService";
|
||||||
|
|
||||||
private final ProfileRepository repository;
|
private final ProfileRepository repository;
|
||||||
private final ProfileRepository wwwRepository;
|
|
||||||
|
|
||||||
private static ProfileService instance;
|
private static ProfileService instance;
|
||||||
|
|
||||||
@ -44,11 +37,7 @@ public class ProfileService extends BaseService {
|
|||||||
final Retrofit retrofit = getRetrofitBuilder()
|
final Retrofit retrofit = getRetrofitBuilder()
|
||||||
.baseUrl("https://i.instagram.com")
|
.baseUrl("https://i.instagram.com")
|
||||||
.build();
|
.build();
|
||||||
final Retrofit wwwRetrofit = getRetrofitBuilder()
|
|
||||||
.baseUrl("https://www.instagram.com")
|
|
||||||
.build();
|
|
||||||
repository = retrofit.create(ProfileRepository.class);
|
repository = retrofit.create(ProfileRepository.class);
|
||||||
wwwRepository = wwwRetrofit.create(ProfileRepository.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ProfileService getInstance() {
|
public static ProfileService getInstance() {
|
||||||
@ -89,32 +78,31 @@ public class ProfileService extends BaseService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fetchPosts(final ProfileModel profileModel,
|
public void fetchPosts(final String userId,
|
||||||
final int postsPerPage,
|
final String maxId,
|
||||||
final String cursor,
|
|
||||||
final ServiceCallback<PostsFetchResponse> callback) {
|
final ServiceCallback<PostsFetchResponse> callback) {
|
||||||
final Map<String, String> queryMap = new HashMap<>();
|
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
||||||
queryMap.put("query_hash", "18a7b935ab438c4514b1f742d8fa07a7");
|
if (!TextUtils.isEmpty(maxId)) {
|
||||||
queryMap.put("variables", "{" +
|
builder.put("max_id", maxId);
|
||||||
"\"id\":\"" + profileModel.getId() + "\"," +
|
}
|
||||||
"\"first\":" + postsPerPage + "," +
|
final Call<String> request = repository.fetch(userId, builder.build());
|
||||||
"\"after\":\"" + (cursor == null ? "" : cursor) + "\"" +
|
|
||||||
"}");
|
|
||||||
final Call<String> request = wwwRepository.fetch(queryMap);
|
|
||||||
request.enqueue(new Callback<String>() {
|
request.enqueue(new Callback<String>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||||
try {
|
try {
|
||||||
// Log.d(TAG, "onResponse: body: " + response.body());
|
if (callback == null) {
|
||||||
final PostsFetchResponse postsFetchResponse = parseResponse(profileModel, response);
|
return;
|
||||||
if (callback != null) {
|
|
||||||
callback.onSuccess(postsFetchResponse);
|
|
||||||
}
|
}
|
||||||
|
final String body = response.body();
|
||||||
|
if (TextUtils.isEmpty(body)) {
|
||||||
|
callback.onSuccess(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final PostsFetchResponse postsFetchResponse = parseProfilePostsResponse(body, false);
|
||||||
|
callback.onSuccess(postsFetchResponse);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.e(TAG, "onResponse", e);
|
Log.e(TAG, "onResponse", e);
|
||||||
if (callback != null) {
|
callback.onFailure(e);
|
||||||
callback.onFailure(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,48 +115,8 @@ public class ProfileService extends BaseService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private PostsFetchResponse parseResponse(final ProfileModel profileModel, final Response<String> response) throws JSONException {
|
|
||||||
if (TextUtils.isEmpty(response.body())) {
|
|
||||||
Log.e(TAG, "parseResponse: feed response body is empty with status code: " + response.code());
|
|
||||||
return new PostsFetchResponse(Collections.emptyList(), false, null);
|
|
||||||
}
|
|
||||||
return parseResponseBody(profileModel, response.body());
|
|
||||||
}
|
|
||||||
|
|
||||||
private PostsFetchResponse parseResponseBody(final ProfileModel profileModel, final String body) throws JSONException {
|
|
||||||
// Log.d(TAG, "parseResponseBody: body: " + body);
|
|
||||||
final List<FeedModel> feedModels = new ArrayList<>();
|
|
||||||
// return new FeedFetchResponse(feedModels, false, null);
|
|
||||||
final JSONObject mediaPosts = new JSONObject(body)
|
|
||||||
.getJSONObject("data")
|
|
||||||
.getJSONObject(Constants.EXTRAS_USER)
|
|
||||||
.getJSONObject("edge_owner_to_timeline_media");
|
|
||||||
final String endCursor;
|
|
||||||
final boolean hasNextPage;
|
|
||||||
final JSONObject pageInfo = mediaPosts.getJSONObject("page_info");
|
|
||||||
if (pageInfo.has("has_next_page")) {
|
|
||||||
hasNextPage = pageInfo.getBoolean("has_next_page");
|
|
||||||
endCursor = hasNextPage ? pageInfo.getString("end_cursor") : null;
|
|
||||||
} else {
|
|
||||||
hasNextPage = false;
|
|
||||||
endCursor = null;
|
|
||||||
}
|
|
||||||
final JSONArray edges = mediaPosts.getJSONArray("edges");
|
|
||||||
for (int i = 0; i < edges.length(); ++i) {
|
|
||||||
final JSONObject itemJson = edges.optJSONObject(i);
|
|
||||||
if (itemJson == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final FeedModel feedModel = ResponseBodyUtils.parseGraphQLItem(itemJson);
|
|
||||||
if (feedModel != null) {
|
|
||||||
feedModels.add(feedModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new PostsFetchResponse(feedModels, hasNextPage, endCursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fetchSaved(final String maxId,
|
public void fetchSaved(final String maxId,
|
||||||
final ServiceCallback<SavedPostsFetchResponse> callback) {
|
final ServiceCallback<PostsFetchResponse> callback) {
|
||||||
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
||||||
if (!TextUtils.isEmpty(maxId)) {
|
if (!TextUtils.isEmpty(maxId)) {
|
||||||
builder.put("max_id", maxId);
|
builder.put("max_id", maxId);
|
||||||
@ -186,8 +134,8 @@ public class ProfileService extends BaseService {
|
|||||||
callback.onSuccess(null);
|
callback.onSuccess(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final SavedPostsFetchResponse savedPostsFetchResponse = parseSavedPostsResponse(body, true);
|
final PostsFetchResponse PostsFetchResponse = parseSavedPostsResponse(body, true);
|
||||||
callback.onSuccess(savedPostsFetchResponse);
|
callback.onSuccess(PostsFetchResponse);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.e(TAG, "onResponse", e);
|
Log.e(TAG, "onResponse", e);
|
||||||
callback.onFailure(e);
|
callback.onFailure(e);
|
||||||
@ -204,7 +152,7 @@ public class ProfileService extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void fetchLiked(final String maxId,
|
public void fetchLiked(final String maxId,
|
||||||
final ServiceCallback<SavedPostsFetchResponse> callback) {
|
final ServiceCallback<PostsFetchResponse> callback) {
|
||||||
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
||||||
if (!TextUtils.isEmpty(maxId)) {
|
if (!TextUtils.isEmpty(maxId)) {
|
||||||
builder.put("max_id", maxId);
|
builder.put("max_id", maxId);
|
||||||
@ -222,8 +170,8 @@ public class ProfileService extends BaseService {
|
|||||||
callback.onSuccess(null);
|
callback.onSuccess(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final SavedPostsFetchResponse savedPostsFetchResponse = parseSavedPostsResponse(body, false);
|
final PostsFetchResponse PostsFetchResponse = parseSavedPostsResponse(body, false);
|
||||||
callback.onSuccess(savedPostsFetchResponse);
|
callback.onSuccess(PostsFetchResponse);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.e(TAG, "onResponse", e);
|
Log.e(TAG, "onResponse", e);
|
||||||
callback.onFailure(e);
|
callback.onFailure(e);
|
||||||
@ -240,17 +188,13 @@ public class ProfileService extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void fetchTagged(final String profileId,
|
public void fetchTagged(final String profileId,
|
||||||
final int postsPerPage,
|
final String maxId,
|
||||||
final String cursor,
|
final ServiceCallback<PostsFetchResponse> callback) {
|
||||||
final ServiceCallback<SavedPostsFetchResponse> callback) {
|
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
||||||
final Map<String, String> queryMap = new HashMap<>();
|
if (!TextUtils.isEmpty(maxId)) {
|
||||||
queryMap.put("query_hash", "31fe64d9463cbbe58319dced405c6206");
|
builder.put("max_id", maxId);
|
||||||
queryMap.put("variables", "{" +
|
}
|
||||||
"\"id\":\"" + profileId + "\"," +
|
final Call<String> request = repository.fetchTagged(profileId, builder.build());
|
||||||
"\"first\":" + postsPerPage + "," +
|
|
||||||
"\"after\":\"" + (cursor == null ? "" : cursor) + "\"" +
|
|
||||||
"}");
|
|
||||||
final Call<String> request = wwwRepository.fetch(queryMap);
|
|
||||||
request.enqueue(new Callback<String>() {
|
request.enqueue(new Callback<String>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||||
@ -263,8 +207,8 @@ public class ProfileService extends BaseService {
|
|||||||
callback.onSuccess(null);
|
callback.onSuccess(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final SavedPostsFetchResponse savedPostsFetchResponse = parseTaggedPostsResponse(body);
|
final PostsFetchResponse PostsFetchResponse = parseSavedPostsResponse(body, false);
|
||||||
callback.onSuccess(savedPostsFetchResponse);
|
callback.onSuccess(PostsFetchResponse);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.e(TAG, "onResponse", e);
|
Log.e(TAG, "onResponse", e);
|
||||||
callback.onFailure(e);
|
callback.onFailure(e);
|
||||||
@ -280,7 +224,7 @@ public class ProfileService extends BaseService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private SavedPostsFetchResponse parseSavedPostsResponse(final String body, final boolean isInMedia) throws JSONException {
|
private PostsFetchResponse parseProfilePostsResponse(final String body, final boolean isInMedia) throws JSONException {
|
||||||
final JSONObject root = new JSONObject(body);
|
final JSONObject root = new JSONObject(body);
|
||||||
final boolean moreAvailable = root.optBoolean("more_available");
|
final boolean moreAvailable = root.optBoolean("more_available");
|
||||||
final String nextMaxId = root.optString("next_max_id");
|
final String nextMaxId = root.optString("next_max_id");
|
||||||
@ -288,48 +232,26 @@ public class ProfileService extends BaseService {
|
|||||||
final String status = root.optString("status");
|
final String status = root.optString("status");
|
||||||
final JSONArray itemsJson = root.optJSONArray("items");
|
final JSONArray itemsJson = root.optJSONArray("items");
|
||||||
final List<FeedModel> items = parseItems(itemsJson, isInMedia);
|
final List<FeedModel> items = parseItems(itemsJson, isInMedia);
|
||||||
return new SavedPostsFetchResponse(
|
return new PostsFetchResponse(
|
||||||
|
items,
|
||||||
moreAvailable,
|
moreAvailable,
|
||||||
nextMaxId,
|
nextMaxId
|
||||||
numResults,
|
|
||||||
status,
|
|
||||||
items
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
private PostsFetchResponse parseSavedPostsResponse(final String body, final boolean isInMedia) throws JSONException {
|
||||||
private SavedPostsFetchResponse parseTaggedPostsResponse(@NonNull final String body)
|
final JSONObject root = new JSONObject(body);
|
||||||
throws JSONException {
|
final boolean moreAvailable = root.optBoolean("more_available");
|
||||||
final List<FeedModel> feedModels = new ArrayList<>();
|
final String nextMaxId = root.optString("next_max_id");
|
||||||
final JSONObject timelineFeed = new JSONObject(body)
|
final int numResults = root.optInt("num_results");
|
||||||
.getJSONObject("data")
|
final String status = root.optString("status");
|
||||||
.getJSONObject(Constants.EXTRAS_USER)
|
final JSONArray itemsJson = root.optJSONArray("items");
|
||||||
.getJSONObject("edge_user_to_photos_of_you");
|
final List<FeedModel> items = parseItems(itemsJson, isInMedia);
|
||||||
final String endCursor;
|
return new PostsFetchResponse(
|
||||||
final boolean hasNextPage;
|
items,
|
||||||
|
moreAvailable,
|
||||||
final JSONObject pageInfo = timelineFeed.getJSONObject("page_info");
|
nextMaxId
|
||||||
if (pageInfo.has("has_next_page")) {
|
);
|
||||||
hasNextPage = pageInfo.getBoolean("has_next_page");
|
|
||||||
endCursor = hasNextPage ? pageInfo.getString("end_cursor") : null;
|
|
||||||
} else {
|
|
||||||
hasNextPage = false;
|
|
||||||
endCursor = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final JSONArray feedItems = timelineFeed.getJSONArray("edges");
|
|
||||||
|
|
||||||
for (int i = 0; i < feedItems.length(); ++i) {
|
|
||||||
final JSONObject itemJson = feedItems.optJSONObject(i);
|
|
||||||
if (itemJson == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final FeedModel feedModel = ResponseBodyUtils.parseGraphQLItem(itemJson);
|
|
||||||
if (feedModel != null) {
|
|
||||||
feedModels.add(feedModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new SavedPostsFetchResponse(hasNextPage, endCursor, timelineFeed.getInt("count"), "ok", feedModels);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<FeedModel> parseItems(final JSONArray items, final boolean isInMedia) throws JSONException {
|
private List<FeedModel> parseItems(final JSONArray items, final boolean isInMedia) throws JSONException {
|
||||||
@ -349,98 +271,4 @@ public class ProfileService extends BaseService {
|
|||||||
}
|
}
|
||||||
return feedModels;
|
return feedModels;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SavedPostsFetchResponse {
|
|
||||||
private boolean moreAvailable;
|
|
||||||
private String nextMaxId;
|
|
||||||
private int numResults;
|
|
||||||
private String status;
|
|
||||||
private List<FeedModel> items;
|
|
||||||
|
|
||||||
public SavedPostsFetchResponse(final boolean moreAvailable,
|
|
||||||
final String nextMaxId,
|
|
||||||
final int numResults,
|
|
||||||
final String status,
|
|
||||||
final List<FeedModel> items) {
|
|
||||||
this.moreAvailable = moreAvailable;
|
|
||||||
this.nextMaxId = nextMaxId;
|
|
||||||
this.numResults = numResults;
|
|
||||||
this.status = status;
|
|
||||||
this.items = items;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMoreAvailable() {
|
|
||||||
return moreAvailable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SavedPostsFetchResponse setMoreAvailable(final boolean moreAvailable) {
|
|
||||||
this.moreAvailable = moreAvailable;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNextMaxId() {
|
|
||||||
return nextMaxId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SavedPostsFetchResponse setNextMaxId(final String nextMaxId) {
|
|
||||||
this.nextMaxId = nextMaxId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNumResults() {
|
|
||||||
return numResults;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SavedPostsFetchResponse setNumResults(final int numResults) {
|
|
||||||
this.numResults = numResults;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SavedPostsFetchResponse setStatus(final String status) {
|
|
||||||
this.status = status;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<FeedModel> getItems() {
|
|
||||||
return items;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SavedPostsFetchResponse setItems(final List<FeedModel> items) {
|
|
||||||
this.items = items;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(final Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
final SavedPostsFetchResponse that = (SavedPostsFetchResponse) o;
|
|
||||||
return moreAvailable == that.moreAvailable &&
|
|
||||||
numResults == that.numResults &&
|
|
||||||
Objects.equals(nextMaxId, that.nextMaxId) &&
|
|
||||||
Objects.equals(status, that.status) &&
|
|
||||||
Objects.equals(items, that.items);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(moreAvailable, nextMaxId, numResults, status, items);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SavedPostsFetchResponse{" +
|
|
||||||
"moreAvailable=" + moreAvailable +
|
|
||||||
", nextMaxId='" + nextMaxId + '\'' +
|
|
||||||
", numResults=" + numResults +
|
|
||||||
", status='" + status + '\'' +
|
|
||||||
", items=" + items +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import java.util.Map;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import awais.instagrabber.models.FeedStoryModel;
|
import awais.instagrabber.models.FeedStoryModel;
|
||||||
|
import awais.instagrabber.models.HighlightModel;
|
||||||
import awais.instagrabber.models.ProfileModel;
|
import awais.instagrabber.models.ProfileModel;
|
||||||
import awais.instagrabber.models.StoryModel;
|
import awais.instagrabber.models.StoryModel;
|
||||||
import awais.instagrabber.models.enums.MediaItemType;
|
import awais.instagrabber.models.enums.MediaItemType;
|
||||||
@ -33,6 +34,7 @@ import awais.instagrabber.repositories.StoriesRepository;
|
|||||||
import awais.instagrabber.repositories.responses.StoryStickerResponse;
|
import awais.instagrabber.repositories.responses.StoryStickerResponse;
|
||||||
import awais.instagrabber.utils.Constants;
|
import awais.instagrabber.utils.Constants;
|
||||||
import awais.instagrabber.utils.ResponseBodyUtils;
|
import awais.instagrabber.utils.ResponseBodyUtils;
|
||||||
|
import awais.instagrabber.utils.TextUtils;
|
||||||
import awais.instagrabber.utils.Utils;
|
import awais.instagrabber.utils.Utils;
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
import retrofit2.Callback;
|
import retrofit2.Callback;
|
||||||
@ -92,7 +94,7 @@ public class StoriesService extends BaseService {
|
|||||||
form.put("_uuid", UUID.randomUUID().toString());
|
form.put("_uuid", UUID.randomUUID().toString());
|
||||||
form.put("supported_capabilities_new", Constants.SUPPORTED_CAPABILITIES);
|
form.put("supported_capabilities_new", Constants.SUPPORTED_CAPABILITIES);
|
||||||
final Map<String, String> signedForm = Utils.sign(form);
|
final Map<String, String> signedForm = Utils.sign(form);
|
||||||
final Call<String> response = repository.getStories(Constants.I_USER_AGENT, signedForm);
|
final Call<String> response = repository.getFeedStories(Constants.I_USER_AGENT, signedForm);
|
||||||
response.enqueue(new Callback<String>() {
|
response.enqueue(new Callback<String>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||||
@ -134,6 +136,52 @@ public class StoriesService extends BaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void fetchHighlights(final String profileId,
|
||||||
|
final ServiceCallback<List<HighlightModel>> callback) {
|
||||||
|
final Call<String> request = repository.fetchHighlights(profileId);
|
||||||
|
request.enqueue(new Callback<String>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||||
|
try {
|
||||||
|
if (callback == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final String body = response.body();
|
||||||
|
if (TextUtils.isEmpty(body)) {
|
||||||
|
callback.onSuccess(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final JSONArray highlightsReel = new JSONObject(body).getJSONArray("tray");
|
||||||
|
|
||||||
|
final int length = highlightsReel.length();
|
||||||
|
final List<HighlightModel> highlightModels = new ArrayList<>();
|
||||||
|
// final String[] highlightIds = new String[length];
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
final JSONObject highlightNode = highlightsReel.getJSONObject(i);
|
||||||
|
highlightModels.add(new HighlightModel(
|
||||||
|
highlightNode.getString("title"),
|
||||||
|
highlightNode.getString(Constants.EXTRAS_ID),
|
||||||
|
highlightNode.getJSONObject("cover_media")
|
||||||
|
.getJSONObject("cropped_image_version")
|
||||||
|
.getString("url")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
callback.onSuccess(highlightModels);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(TAG, "onResponse", e);
|
||||||
|
callback.onFailure(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
||||||
|
if (callback != null) {
|
||||||
|
callback.onFailure(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void getUserStory(final String id,
|
public void getUserStory(final String id,
|
||||||
final String username,
|
final String username,
|
||||||
final boolean isLoc,
|
final boolean isLoc,
|
||||||
|
@ -19,6 +19,7 @@ import java.util.Objects;
|
|||||||
|
|
||||||
import awais.instagrabber.models.FeedModel;
|
import awais.instagrabber.models.FeedModel;
|
||||||
import awais.instagrabber.repositories.TagsRepository;
|
import awais.instagrabber.repositories.TagsRepository;
|
||||||
|
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||||
import awais.instagrabber.utils.Constants;
|
import awais.instagrabber.utils.Constants;
|
||||||
import awais.instagrabber.utils.ResponseBodyUtils;
|
import awais.instagrabber.utils.ResponseBodyUtils;
|
||||||
import awais.instagrabber.utils.TextUtils;
|
import awais.instagrabber.utils.TextUtils;
|
||||||
@ -118,8 +119,8 @@ public class TagsService extends BaseService {
|
|||||||
|
|
||||||
public void fetchPosts(@NonNull final String tag,
|
public void fetchPosts(@NonNull final String tag,
|
||||||
final String maxId,
|
final String maxId,
|
||||||
final ServiceCallback<TagPostsFetchResponse> callback) {
|
final ServiceCallback<PostsFetchResponse> callback) {
|
||||||
final ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, String>builder();
|
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
||||||
if (!TextUtils.isEmpty(maxId)) {
|
if (!TextUtils.isEmpty(maxId)) {
|
||||||
builder.put("max_id", maxId);
|
builder.put("max_id", maxId);
|
||||||
}
|
}
|
||||||
@ -136,7 +137,7 @@ public class TagsService extends BaseService {
|
|||||||
callback.onSuccess(null);
|
callback.onSuccess(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final TagPostsFetchResponse tagPostsFetchResponse = parseResponse(body);
|
final PostsFetchResponse tagPostsFetchResponse = parseResponse(body);
|
||||||
callback.onSuccess(tagPostsFetchResponse);
|
callback.onSuccess(tagPostsFetchResponse);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.e(TAG, "onResponse", e);
|
Log.e(TAG, "onResponse", e);
|
||||||
@ -153,7 +154,7 @@ public class TagsService extends BaseService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private TagPostsFetchResponse parseResponse(@NonNull final String body) throws JSONException {
|
private PostsFetchResponse parseResponse(@NonNull final String body) throws JSONException {
|
||||||
final JSONObject root = new JSONObject(body);
|
final JSONObject root = new JSONObject(body);
|
||||||
final boolean moreAvailable = root.optBoolean("more_available");
|
final boolean moreAvailable = root.optBoolean("more_available");
|
||||||
final String nextMaxId = root.optString("next_max_id");
|
final String nextMaxId = root.optString("next_max_id");
|
||||||
@ -161,12 +162,10 @@ public class TagsService extends BaseService {
|
|||||||
final String status = root.optString("status");
|
final String status = root.optString("status");
|
||||||
final JSONArray itemsJson = root.optJSONArray("items");
|
final JSONArray itemsJson = root.optJSONArray("items");
|
||||||
final List<FeedModel> items = parseItems(itemsJson);
|
final List<FeedModel> items = parseItems(itemsJson);
|
||||||
return new TagPostsFetchResponse(
|
return new PostsFetchResponse(
|
||||||
|
items,
|
||||||
moreAvailable,
|
moreAvailable,
|
||||||
nextMaxId,
|
nextMaxId
|
||||||
numResults,
|
|
||||||
status,
|
|
||||||
items
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,174 +186,4 @@ public class TagsService extends BaseService {
|
|||||||
}
|
}
|
||||||
return feedModels;
|
return feedModels;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fetchGraphQLPosts(@NonNull final String tag,
|
|
||||||
final String maxId,
|
|
||||||
final ServiceCallback<TagPostsFetchResponse> callback) {
|
|
||||||
final Map<String, String> queryMap = new HashMap<>();
|
|
||||||
queryMap.put("query_hash", "9b498c08113f1e09617a1703c22b2f32");
|
|
||||||
queryMap.put("variables", "{" +
|
|
||||||
"\"tag_name\":\"" + tag + "\"," +
|
|
||||||
"\"first\":25," +
|
|
||||||
"\"after\":\"" + (maxId == null ? "" : maxId) + "\"" +
|
|
||||||
"}");
|
|
||||||
final Call<String> request = webRepository.fetchGraphQLPosts(queryMap);
|
|
||||||
request.enqueue(new Callback<String>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
|
||||||
try {
|
|
||||||
if (callback == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final String body = response.body();
|
|
||||||
if (TextUtils.isEmpty(body)) {
|
|
||||||
callback.onSuccess(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final TagPostsFetchResponse tagPostsFetchResponse = parseGraphQLResponse(body);
|
|
||||||
callback.onSuccess(tagPostsFetchResponse);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.e(TAG, "onResponse", e);
|
|
||||||
callback.onFailure(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
|
||||||
if (callback != null) {
|
|
||||||
callback.onFailure(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private TagPostsFetchResponse parseGraphQLResponse(@NonNull final String body) throws JSONException {
|
|
||||||
final JSONObject rootroot = new JSONObject(body);
|
|
||||||
final JSONObject root = rootroot.getJSONObject("data").getJSONObject("hashtag").getJSONObject("edge_hashtag_to_media");
|
|
||||||
final boolean moreAvailable = root.getJSONObject("page_info").optBoolean("has_next_page");
|
|
||||||
final String nextMaxId = root.getJSONObject("page_info").optString("end_cursor");
|
|
||||||
final int numResults = root.optInt("count");
|
|
||||||
final String status = rootroot.optString("status");
|
|
||||||
final JSONArray itemsJson = root.optJSONArray("edges");
|
|
||||||
final List<FeedModel> items = parseGraphQLItems(itemsJson);
|
|
||||||
return new TagPostsFetchResponse(
|
|
||||||
moreAvailable,
|
|
||||||
nextMaxId,
|
|
||||||
numResults,
|
|
||||||
status,
|
|
||||||
items
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<FeedModel> parseGraphQLItems(final JSONArray items) throws JSONException {
|
|
||||||
if (items == null) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
final List<FeedModel> feedModels = new ArrayList<>();
|
|
||||||
for (int i = 0; i < items.length(); i++) {
|
|
||||||
final JSONObject itemJson = items.optJSONObject(i);
|
|
||||||
if (itemJson == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final FeedModel feedModel = ResponseBodyUtils.parseGraphQLItem(itemJson);
|
|
||||||
if (feedModel != null) {
|
|
||||||
feedModels.add(feedModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return feedModels;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class TagPostsFetchResponse {
|
|
||||||
private boolean moreAvailable;
|
|
||||||
private String nextMaxId;
|
|
||||||
private int numResults;
|
|
||||||
private String status;
|
|
||||||
private List<FeedModel> items;
|
|
||||||
|
|
||||||
public TagPostsFetchResponse(final boolean moreAvailable,
|
|
||||||
final String nextMaxId,
|
|
||||||
final int numResults,
|
|
||||||
final String status,
|
|
||||||
final List<FeedModel> items) {
|
|
||||||
this.moreAvailable = moreAvailable;
|
|
||||||
this.nextMaxId = nextMaxId;
|
|
||||||
this.numResults = numResults;
|
|
||||||
this.status = status;
|
|
||||||
this.items = items;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMoreAvailable() {
|
|
||||||
return moreAvailable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TagPostsFetchResponse setMoreAvailable(final boolean moreAvailable) {
|
|
||||||
this.moreAvailable = moreAvailable;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNextMaxId() {
|
|
||||||
return nextMaxId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TagPostsFetchResponse setNextMaxId(final String nextMaxId) {
|
|
||||||
this.nextMaxId = nextMaxId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNumResults() {
|
|
||||||
return numResults;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TagPostsFetchResponse setNumResults(final int numResults) {
|
|
||||||
this.numResults = numResults;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TagPostsFetchResponse setStatus(final String status) {
|
|
||||||
this.status = status;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<FeedModel> getItems() {
|
|
||||||
return items;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TagPostsFetchResponse setItems(final List<FeedModel> items) {
|
|
||||||
this.items = items;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(final Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
final TagPostsFetchResponse that = (TagPostsFetchResponse) o;
|
|
||||||
return moreAvailable == that.moreAvailable &&
|
|
||||||
numResults == that.numResults &&
|
|
||||||
Objects.equals(nextMaxId, that.nextMaxId) &&
|
|
||||||
Objects.equals(status, that.status) &&
|
|
||||||
Objects.equals(items, that.items);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(moreAvailable, nextMaxId, numResults, status, items);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "TagPostsFetchResponse{" +
|
|
||||||
"moreAvailable=" + moreAvailable +
|
|
||||||
", nextMaxId='" + nextMaxId + '\'' +
|
|
||||||
", numResults=" + numResults +
|
|
||||||
", status='" + status + '\'' +
|
|
||||||
", items=" + items +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user