mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-09-19 09:37:29 +00:00
278 lines
14 KiB
Java
278 lines
14 KiB
Java
package awais.instagrabber.webservices;
|
|
|
|
import android.util.Log;
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import org.json.JSONArray;
|
|
import org.json.JSONException;
|
|
import org.json.JSONObject;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
import awais.instagrabber.models.FeedStoryModel;
|
|
import awais.instagrabber.models.ProfileModel;
|
|
import awais.instagrabber.models.StoryModel;
|
|
import awais.instagrabber.models.enums.MediaItemType;
|
|
import awais.instagrabber.models.stickers.PollModel;
|
|
import awais.instagrabber.models.stickers.QuestionModel;
|
|
import awais.instagrabber.models.stickers.QuizModel;
|
|
import awais.instagrabber.repositories.StoriesRepository;
|
|
import awais.instagrabber.utils.Constants;
|
|
import awais.instagrabber.utils.ResponseBodyUtils;
|
|
import retrofit2.Call;
|
|
import retrofit2.Callback;
|
|
import retrofit2.Response;
|
|
import retrofit2.Retrofit;
|
|
|
|
public class StoriesService extends BaseService {
|
|
private static final String TAG = "StoriesService";
|
|
|
|
private final StoriesRepository repository;
|
|
|
|
private static StoriesService instance;
|
|
|
|
private StoriesService() {
|
|
final Retrofit retrofit = getRetrofitBuilder()
|
|
.baseUrl("https://www.instagram.com")
|
|
.build();
|
|
repository = retrofit.create(StoriesRepository.class);
|
|
}
|
|
|
|
public static StoriesService getInstance() {
|
|
if (instance == null) {
|
|
instance = new StoriesService();
|
|
}
|
|
return instance;
|
|
}
|
|
|
|
public void getFeedStories(final ServiceCallback<List<FeedStoryModel>> callback) {
|
|
final Map<String, String> queryMap = new HashMap<>();
|
|
queryMap.put("query_hash", "b7b84d884400bc5aa7cfe12ae843a091");
|
|
queryMap.put("variables", "{\"only_stories\":true,\"stories_prefetch\":false,\"stories_video_dash_manifest\":false}");
|
|
final Call<String> response = repository.getStories(queryMap);
|
|
response.enqueue(new Callback<String>() {
|
|
@Override
|
|
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
|
final String body = response.body();
|
|
if (body == null) {
|
|
Log.e(TAG, "getFeedStories: body is empty");
|
|
return;
|
|
}
|
|
try {
|
|
final List<FeedStoryModel> feedStoryModels = new ArrayList<>();
|
|
final JSONArray feedStoriesReel = new JSONObject(body)
|
|
.getJSONObject("data")
|
|
.getJSONObject(Constants.EXTRAS_USER)
|
|
.getJSONObject("feed_reels_tray")
|
|
.getJSONObject("edge_reels_tray_to_reel")
|
|
.getJSONArray("edges");
|
|
for (int i = 0; i < feedStoriesReel.length(); ++i) {
|
|
final JSONObject node = feedStoriesReel.getJSONObject(i).getJSONObject("node");
|
|
final JSONObject user = node.getJSONObject(node.has("user") ? "user" : "owner");
|
|
final ProfileModel profileModel = new ProfileModel(false, false, false,
|
|
user.getString("id"),
|
|
user.getString("username"),
|
|
null, null, null,
|
|
user.getString("profile_pic_url"),
|
|
null, 0, 0, 0, false, false, false, false);
|
|
final String id = node.getString("id");
|
|
final boolean fullyRead = !node.isNull("seen") && node.getLong("seen") == node.getLong("latest_reel_media");
|
|
feedStoryModels.add(new FeedStoryModel(id, profileModel, fullyRead));
|
|
}
|
|
callback.onSuccess(feedStoryModels);
|
|
} catch (JSONException e) {
|
|
Log.e(TAG, "Error parsing json", e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
|
callback.onFailure(t);
|
|
}
|
|
});
|
|
}
|
|
|
|
public void getUserStory(final String id,
|
|
final String username,
|
|
final boolean storiesig,
|
|
final boolean isLoc,
|
|
final boolean isHashtag,
|
|
final boolean highlight,
|
|
final ServiceCallback<List<StoryModel>> callback) {
|
|
final String url = buildUrl(id, storiesig, isLoc, isHashtag, highlight);
|
|
final String userAgent = storiesig ? Constants.A_USER_AGENT : Constants.I_USER_AGENT;
|
|
final Call<String> userStoryCall = repository.getUserStory(userAgent, url);
|
|
userStoryCall.enqueue(new Callback<String>() {
|
|
@Override
|
|
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
|
JSONObject data;
|
|
String localUsername = username;
|
|
try {
|
|
final String body = response.body();
|
|
if (body == null) {
|
|
Log.e(TAG, "body is null");
|
|
return;
|
|
}
|
|
data = new JSONObject(body);
|
|
|
|
if (!storiesig && !highlight)
|
|
data = data.optJSONObject((isLoc || isHashtag) ? "story" : "reel");
|
|
else if (highlight) data = data.getJSONObject("reels").optJSONObject(id);
|
|
|
|
if (data != null
|
|
&& localUsername == null
|
|
&& !isLoc
|
|
&& !isHashtag)
|
|
localUsername = data.getJSONObject("user").getString("username");
|
|
|
|
JSONArray media;
|
|
if (data != null
|
|
&& (media = data.optJSONArray("items")) != null
|
|
&& media.length() > 0 && media.optJSONObject(0) != null) {
|
|
|
|
final int mediaLen = media.length();
|
|
final List<StoryModel> models = new ArrayList<>();
|
|
for (int i = 0; i < mediaLen; ++i) {
|
|
data = media.getJSONObject(i);
|
|
final boolean isVideo = data.has("video_duration");
|
|
final StoryModel model = new StoryModel(data.getString("id"),
|
|
data.getJSONObject("image_versions2").getJSONArray("candidates").getJSONObject(0).getString("url"),
|
|
isVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE,
|
|
data.optLong("taken_at", 0),
|
|
(isLoc || isHashtag) ? data.getJSONObject("user").getString("username") : localUsername,
|
|
data.getJSONObject("user").getString("pk"),
|
|
data.getBoolean("can_reply"));
|
|
|
|
final JSONArray videoResources = data.optJSONArray("video_versions");
|
|
if (isVideo && videoResources != null)
|
|
model.setVideoUrl(ResponseBodyUtils.getHighQualityPost(videoResources, true, true, false));
|
|
|
|
if (data.has("story_feed_media")) {
|
|
model.setTappableShortCode(data.getJSONArray("story_feed_media").getJSONObject(0).optString("media_id"));
|
|
}
|
|
|
|
if (!data.isNull("story_app_attribution"))
|
|
model.setSpotify(data.getJSONObject("story_app_attribution").optString("content_url").split("\\?")[0]);
|
|
|
|
if (data.has("story_polls")) {
|
|
final JSONArray storyPolls = data.optJSONArray("story_polls");
|
|
JSONObject tappableObject = null;
|
|
if (storyPolls != null) {
|
|
tappableObject = storyPolls.getJSONObject(0).optJSONObject("poll_sticker");
|
|
}
|
|
if (tappableObject != null) model.setPoll(new PollModel(
|
|
String.valueOf(tappableObject.getLong("poll_id")),
|
|
tappableObject.getString("question"),
|
|
tappableObject.getJSONArray("tallies").getJSONObject(0).getString("text"),
|
|
tappableObject.getJSONArray("tallies").getJSONObject(0).getInt("count"),
|
|
tappableObject.getJSONArray("tallies").getJSONObject(1).getString("text"),
|
|
tappableObject.getJSONArray("tallies").getJSONObject(1).getInt("count"),
|
|
tappableObject.optInt("viewer_vote", -1)
|
|
));
|
|
}
|
|
if (data.has("story_questions")) {
|
|
JSONObject tappableObject = data.getJSONArray("story_questions").getJSONObject(0).optJSONObject("question_sticker");
|
|
if (tappableObject != null && !tappableObject.getString("question_type").equals("music"))
|
|
model.setQuestion(new QuestionModel(
|
|
String.valueOf(tappableObject.getLong("question_id")),
|
|
tappableObject.getString("question")
|
|
));
|
|
}
|
|
if (data.has("story_quizs")) {
|
|
JSONObject tappableObject = data.getJSONArray("story_quizs").getJSONObject(0).optJSONObject("quiz_sticker");
|
|
if (tappableObject != null) {
|
|
String[] choices = new String[tappableObject.getJSONArray("tallies").length()];
|
|
Long[] counts = new Long[choices.length];
|
|
for (int q = 0; q < choices.length; ++q) {
|
|
JSONObject tempchoice = tappableObject.getJSONArray("tallies").getJSONObject(q);
|
|
choices[q] = (q == tappableObject.getInt("correct_answer") ? "*** " : "")
|
|
+ tempchoice.getString("text");
|
|
counts[q] = tempchoice.getLong("count");
|
|
}
|
|
model.setQuiz(new QuizModel(
|
|
String.valueOf(tappableObject.getLong("quiz_id")),
|
|
tappableObject.getString("question"),
|
|
choices,
|
|
counts,
|
|
tappableObject.optInt("viewer_answer", -1)
|
|
));
|
|
}
|
|
}
|
|
JSONArray hashtags = data.optJSONArray("story_hashtags");
|
|
JSONArray locations = data.optJSONArray("story_locations");
|
|
JSONArray atmarks = data.optJSONArray("reel_mentions");
|
|
String[] mentions = new String[(hashtags == null ? 0 : hashtags.length())
|
|
+ (atmarks == null ? 0 : atmarks.length())
|
|
+ (locations == null ? 0 : locations.length())];
|
|
if (hashtags != null) {
|
|
for (int h = 0; h < hashtags.length(); ++h) {
|
|
mentions[h] = "#" + hashtags.getJSONObject(h).getJSONObject("hashtag").getString("name");
|
|
}
|
|
}
|
|
if (atmarks != null) {
|
|
for (int h = 0; h < atmarks.length(); ++h) {
|
|
mentions[h + (hashtags == null ? 0 : hashtags.length())] =
|
|
"@" + atmarks.getJSONObject(h).getJSONObject("user").getString("username");
|
|
}
|
|
}
|
|
if (locations != null) {
|
|
for (int h = 0; h < locations.length(); ++h) {
|
|
mentions[h + (hashtags == null ? 0 : hashtags.length()) + (atmarks == null ? 0 : atmarks.length())] =
|
|
locations.getJSONObject(h).getJSONObject("location").getLong("pk")
|
|
+ "/ (" + locations.getJSONObject(h).getJSONObject("location").getString("short_name") + ")";
|
|
}
|
|
}
|
|
if (mentions.length != 0) model.setMentions(mentions);
|
|
models.add(model);
|
|
}
|
|
callback.onSuccess(models);
|
|
}
|
|
} catch (JSONException e) {
|
|
Log.e(TAG, "Error parsing string");
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
|
callback.onFailure(t);
|
|
}
|
|
});
|
|
}
|
|
|
|
private String buildUrl(final String id, final boolean storiesig, final boolean isLoc, final boolean isHashtag, final boolean highlight) {
|
|
final String userId = id.replace(":", "%3A");
|
|
final StringBuilder builder = new StringBuilder();
|
|
builder.append("https://");
|
|
if (storiesig) {
|
|
builder.append("storiesig");
|
|
} else {
|
|
builder.append("i.instagram");
|
|
}
|
|
builder.append(".com/api/v1/");
|
|
if (isLoc) {
|
|
builder.append("locations/");
|
|
}
|
|
if (isHashtag) {
|
|
builder.append("tags/");
|
|
}
|
|
if (highlight) {
|
|
builder.append("feed/reels_media?user_ids=");
|
|
} else {
|
|
builder.append("feed/user/");
|
|
}
|
|
builder.append(userId);
|
|
if (!highlight) {
|
|
if (storiesig) {
|
|
builder.append("/reel_media/");
|
|
} else {
|
|
builder.append("/story/");
|
|
}
|
|
}
|
|
return builder.toString();
|
|
}
|
|
}
|