mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-12-23 05:16:58 +00:00
convert HashtagFetcher
This commit is contained in:
parent
839e30a4e5
commit
6fec6f5c86
@ -714,7 +714,7 @@ public class MainActivity extends BaseLanguageActivity implements FragmentManage
|
||||
final NavController navController = currentNavControllerLiveData.getValue();
|
||||
if (navController == null) return;
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putString("hashtag", "#" + hashtag);
|
||||
bundle.putString("hashtag", hashtag);
|
||||
navController.navigate(R.id.action_global_hashTagFragment, bundle);
|
||||
}
|
||||
|
||||
|
@ -1,102 +0,0 @@
|
||||
package awais.instagrabber.asyncs;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
import awais.instagrabber.BuildConfig;
|
||||
import awais.instagrabber.interfaces.FetchListener;
|
||||
import awais.instagrabber.models.HashtagModel;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.NetworkUtils;
|
||||
//import awaisomereport.LogCollector;
|
||||
|
||||
//import static awais.instagrabber.utils.Utils.logCollector;
|
||||
|
||||
public final class HashtagFetcher extends AsyncTask<Void, Void, HashtagModel> {
|
||||
private static final String TAG = "HashtagFetcher";
|
||||
|
||||
private final FetchListener<HashtagModel> fetchListener;
|
||||
private final String hashtag;
|
||||
|
||||
public HashtagFetcher(String hashtag, FetchListener<HashtagModel> fetchListener) {
|
||||
this.hashtag = hashtag;
|
||||
this.fetchListener = fetchListener;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected HashtagModel doInBackground(final Void... voids) {
|
||||
HashtagModel result = null;
|
||||
|
||||
try {
|
||||
final HttpURLConnection conn = (HttpURLConnection) new URL("https://www.instagram.com/explore/tags/" + hashtag + "/?__a=1")
|
||||
.openConnection();
|
||||
conn.setUseCaches(true);
|
||||
conn.connect();
|
||||
|
||||
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
||||
final JSONObject user = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONObject("graphql")
|
||||
.getJSONObject(Constants.EXTRAS_HASHTAG);
|
||||
|
||||
final JSONObject timelineMedia = user.getJSONObject("edge_hashtag_to_media");
|
||||
if (timelineMedia.has("edges")) {
|
||||
final JSONArray edges = timelineMedia.getJSONArray("edges");
|
||||
}
|
||||
|
||||
result = new HashtagModel(
|
||||
user.getString(Constants.EXTRAS_ID),
|
||||
user.getString("name"),
|
||||
user.getString("profile_pic_url"),
|
||||
timelineMedia.getLong("count"),
|
||||
user.optBoolean("is_following"));
|
||||
} else {
|
||||
BufferedReader bufferedReader = null;
|
||||
try {
|
||||
final InputStream responseInputStream = conn.getErrorStream();
|
||||
bufferedReader = new BufferedReader(new InputStreamReader(responseInputStream));
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for (String line = bufferedReader.readLine(); line != null; line = bufferedReader.readLine()) {
|
||||
if (builder.length() != 0) {
|
||||
builder.append("\n");
|
||||
}
|
||||
builder.append(line);
|
||||
}
|
||||
Log.d(TAG, "doInBackground: " + builder.toString());
|
||||
} finally {
|
||||
if (bufferedReader != null) {
|
||||
try {
|
||||
bufferedReader.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
conn.disconnect();
|
||||
} catch (final Exception e) {
|
||||
// if (logCollector != null)
|
||||
// logCollector.appendException(e, LogCollector.LogFile.ASYNC_HASHTAG_FETCHER, "doInBackground");
|
||||
if (BuildConfig.DEBUG) Log.e(TAG, "", e);
|
||||
if (fetchListener != null) fetchListener.onFailure(e);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final HashtagModel result) {
|
||||
if (fetchListener != null) fetchListener.onResult(result);
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ import java.util.List;
|
||||
|
||||
import awais.instagrabber.customviews.helpers.PostFetcher;
|
||||
import awais.instagrabber.interfaces.FetchListener;
|
||||
import awais.instagrabber.models.HashtagModel;
|
||||
import awais.instagrabber.repositories.responses.Hashtag;
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||
import awais.instagrabber.webservices.GraphQLService;
|
||||
@ -14,12 +14,12 @@ import awais.instagrabber.webservices.TagsService;
|
||||
public class HashtagPostFetchService implements PostFetcher.PostFetchService {
|
||||
private final TagsService tagsService;
|
||||
private final GraphQLService graphQLService;
|
||||
private final HashtagModel hashtagModel;
|
||||
private final Hashtag hashtagModel;
|
||||
private String nextMaxId;
|
||||
private boolean moreAvailable;
|
||||
private final boolean isLoggedIn;
|
||||
|
||||
public HashtagPostFetchService(final HashtagModel hashtagModel, final boolean isLoggedIn) {
|
||||
public HashtagPostFetchService(final Hashtag hashtagModel, final boolean isLoggedIn) {
|
||||
this.hashtagModel = hashtagModel;
|
||||
this.isLoggedIn = isLoggedIn;
|
||||
tagsService = isLoggedIn ? TagsService.getInstance() : null;
|
||||
|
@ -43,7 +43,6 @@ import java.util.Set;
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.activities.MainActivity;
|
||||
import awais.instagrabber.adapters.FeedAdapterV2;
|
||||
import awais.instagrabber.asyncs.HashtagFetcher;
|
||||
import awais.instagrabber.asyncs.HashtagPostFetchService;
|
||||
import awais.instagrabber.asyncs.PostFetcher;
|
||||
import awais.instagrabber.customviews.PrimaryActionModeCallback;
|
||||
@ -54,12 +53,12 @@ import awais.instagrabber.db.entities.Favorite;
|
||||
import awais.instagrabber.db.repositories.FavoriteRepository;
|
||||
import awais.instagrabber.db.repositories.RepositoryCallback;
|
||||
import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment;
|
||||
import awais.instagrabber.interfaces.FetchListener;
|
||||
import awais.instagrabber.models.HashtagModel;
|
||||
import awais.instagrabber.models.PostsLayoutPreferences;
|
||||
import awais.instagrabber.models.StoryModel;
|
||||
import awais.instagrabber.models.enums.FavoriteType;
|
||||
import awais.instagrabber.models.enums.FollowingType;
|
||||
import awais.instagrabber.repositories.requests.StoryViewerOptions;
|
||||
import awais.instagrabber.repositories.responses.Hashtag;
|
||||
import awais.instagrabber.repositories.responses.Location;
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
@ -67,16 +66,18 @@ import awais.instagrabber.utils.CookieUtils;
|
||||
import awais.instagrabber.utils.DownloadUtils;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
import awais.instagrabber.webservices.GraphQLService;
|
||||
import awais.instagrabber.webservices.ServiceCallback;
|
||||
import awais.instagrabber.webservices.StoriesService;
|
||||
import awais.instagrabber.webservices.TagsService;
|
||||
//import awaisomereport.LogCollector;
|
||||
|
||||
import static androidx.core.content.PermissionChecker.checkSelfPermission;
|
||||
import static awais.instagrabber.utils.DownloadUtils.WRITE_PERMISSION;
|
||||
//import static awais.instagrabber.utils.Utils.logCollector;
|
||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||
|
||||
//import awaisomereport.LogCollector;
|
||||
//import static awais.instagrabber.utils.Utils.logCollector;
|
||||
|
||||
public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
|
||||
private static final String TAG = "HashTagFragment";
|
||||
private static final int STORAGE_PERM_REQUEST_CODE = 8020;
|
||||
@ -91,12 +92,13 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
private boolean hasStories = false;
|
||||
private boolean opening = false;
|
||||
private String hashtag;
|
||||
private HashtagModel hashtagModel = null;
|
||||
private Hashtag hashtagModel = null;
|
||||
private ActionMode actionMode;
|
||||
private StoriesService storiesService;
|
||||
private AsyncTask<?, ?, ?> currentlyExecuting;
|
||||
private boolean isLoggedIn;
|
||||
private TagsService tagsService;
|
||||
private GraphQLService graphQLService;
|
||||
private boolean storiesFetching;
|
||||
private Set<Media> selectedFeedModels;
|
||||
private Media downloadFeedModel;
|
||||
@ -270,13 +272,29 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
}
|
||||
}
|
||||
};
|
||||
private final ServiceCallback<Hashtag> cb = new ServiceCallback<Hashtag>() {
|
||||
@Override
|
||||
public void onSuccess(final Hashtag result) {
|
||||
hashtagModel = result;
|
||||
binding.swipeRefreshLayout.setRefreshing(false);
|
||||
setHashtagDetails();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable t) {
|
||||
setHashtagDetails();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
fragmentActivity = (MainActivity) requireActivity();
|
||||
tagsService = TagsService.getInstance();
|
||||
storiesService = StoriesService.getInstance(null, 0L, null);
|
||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
|
||||
tagsService = isLoggedIn ? TagsService.getInstance() : null;
|
||||
storiesService = isLoggedIn ? StoriesService.getInstance(null, 0L, null) : null;
|
||||
graphQLService = isLoggedIn ? null : GraphQLService.getInstance();
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@ -358,29 +376,15 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
|
||||
private void init() {
|
||||
if (getArguments() == null) return;
|
||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||
isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) > 0;
|
||||
final HashTagFragmentArgs fragmentArgs = HashTagFragmentArgs.fromBundle(getArguments());
|
||||
hashtag = fragmentArgs.getHashtag();
|
||||
fetchHashtagModel();
|
||||
}
|
||||
|
||||
private void fetchHashtagModel() {
|
||||
stopCurrentExecutor();
|
||||
binding.swipeRefreshLayout.setRefreshing(true);
|
||||
currentlyExecuting = new HashtagFetcher(hashtag.substring(1), new FetchListener<HashtagModel>() {
|
||||
@Override
|
||||
public void onResult(final HashtagModel result) {
|
||||
hashtagModel = result;
|
||||
binding.swipeRefreshLayout.setRefreshing(false);
|
||||
setHashtagDetails();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
setHashtagDetails();
|
||||
}
|
||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
if (isLoggedIn) tagsService.fetch(hashtag, cb);
|
||||
else graphQLService.fetchTag(hashtag, cb);
|
||||
}
|
||||
|
||||
private void setupPosts() {
|
||||
@ -409,8 +413,10 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
fetchStories();
|
||||
if (isLoggedIn) {
|
||||
hashtagDetailsBinding.btnFollowTag.setVisibility(View.VISIBLE);
|
||||
hashtagDetailsBinding.btnFollowTag.setText(hashtagModel.getFollowing() ? R.string.unfollow : R.string.follow);
|
||||
hashtagDetailsBinding.btnFollowTag.setChipIconResource(hashtagModel.getFollowing()
|
||||
hashtagDetailsBinding.btnFollowTag.setText(hashtagModel.getFollowing() == FollowingType.FOLLOWING
|
||||
? R.string.unfollow
|
||||
: R.string.follow);
|
||||
hashtagDetailsBinding.btnFollowTag.setChipIconResource(hashtagModel.getFollowing() == FollowingType.FOLLOWING
|
||||
? R.drawable.ic_outline_person_add_disabled_24
|
||||
: R.drawable.ic_outline_person_add_24);
|
||||
hashtagDetailsBinding.btnFollowTag.setOnClickListener(v -> {
|
||||
@ -420,36 +426,12 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
final String deviceUuid = Utils.settingsHelper.getString(Constants.DEVICE_UUID);
|
||||
if (csrfToken != null && userId != 0 && deviceUuid != null) {
|
||||
hashtagDetailsBinding.btnFollowTag.setClickable(false);
|
||||
if (!hashtagModel.getFollowing()) {
|
||||
tagsService.follow(hashtag.substring(1), csrfToken, userId, deviceUuid, new ServiceCallback<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(final Boolean result) {
|
||||
hashtagDetailsBinding.btnFollowTag.setClickable(true);
|
||||
if (!result) {
|
||||
Log.e(TAG, "onSuccess: result is false");
|
||||
Snackbar.make(root, R.string.downloader_unknown_error, BaseTransientBottomBar.LENGTH_LONG)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
hashtagDetailsBinding.btnFollowTag.setText(R.string.unfollow);
|
||||
hashtagDetailsBinding.btnFollowTag.setChipIconResource(R.drawable.ic_outline_person_add_disabled_24);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull final Throwable t) {
|
||||
hashtagDetailsBinding.btnFollowTag.setClickable(true);
|
||||
Log.e(TAG, "onFailure: ", t);
|
||||
final String message = t.getMessage();
|
||||
Snackbar.make(root,
|
||||
message != null ? message
|
||||
: getString(R.string.downloader_unknown_error),
|
||||
BaseTransientBottomBar.LENGTH_LONG)
|
||||
.show();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
tagsService.unfollow(hashtag.substring(1), csrfToken, userId, deviceUuid, new ServiceCallback<Boolean>() {
|
||||
tagsService.changeFollow(hashtagModel.getFollowing() == FollowingType.FOLLOWING ? "unfollow" : "follow",
|
||||
hashtag,
|
||||
csrfToken,
|
||||
userId,
|
||||
deviceUuid,
|
||||
new ServiceCallback<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(final Boolean result) {
|
||||
hashtagDetailsBinding.btnFollowTag.setClickable(true);
|
||||
@ -459,8 +441,8 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
hashtagDetailsBinding.btnFollowTag.setText(R.string.follow);
|
||||
hashtagDetailsBinding.btnFollowTag.setChipIconResource(R.drawable.ic_outline_person_add_24);
|
||||
hashtagDetailsBinding.btnFollowTag.setText(R.string.unfollow);
|
||||
hashtagDetailsBinding.btnFollowTag.setChipIconResource(R.drawable.ic_outline_person_add_disabled_24);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -475,6 +457,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
.show();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -482,15 +465,15 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
}
|
||||
hashtagDetailsBinding.favChip.setVisibility(View.VISIBLE);
|
||||
final FavoriteRepository favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(getContext()));
|
||||
favoriteRepository.getFavorite(hashtag.substring(1), FavoriteType.HASHTAG, new RepositoryCallback<Favorite>() {
|
||||
favoriteRepository.getFavorite(hashtag, FavoriteType.HASHTAG, new RepositoryCallback<Favorite>() {
|
||||
@Override
|
||||
public void onSuccess(final Favorite result) {
|
||||
favoriteRepository.insertOrUpdateFavorite(new Favorite(
|
||||
result.getId(),
|
||||
hashtag.substring(1),
|
||||
hashtag,
|
||||
FavoriteType.HASHTAG,
|
||||
hashtagModel.getName(),
|
||||
hashtagModel.getSdProfilePic(),
|
||||
hashtagModel.getProfilePicUrl(),
|
||||
result.getDateAdded()
|
||||
), new RepositoryCallback<Void>() {
|
||||
@Override
|
||||
@ -511,10 +494,10 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
}
|
||||
});
|
||||
hashtagDetailsBinding.favChip.setOnClickListener(
|
||||
v -> favoriteRepository.getFavorite(hashtag.substring(1), FavoriteType.HASHTAG, new RepositoryCallback<Favorite>() {
|
||||
v -> favoriteRepository.getFavorite(hashtag, FavoriteType.HASHTAG, new RepositoryCallback<Favorite>() {
|
||||
@Override
|
||||
public void onSuccess(final Favorite result) {
|
||||
favoriteRepository.deleteFavorite(hashtag.substring(1), FavoriteType.HASHTAG, new RepositoryCallback<Void>() {
|
||||
favoriteRepository.deleteFavorite(hashtag, FavoriteType.HASHTAG, new RepositoryCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(final Void result) {
|
||||
hashtagDetailsBinding.favChip.setText(R.string.add_to_favorites);
|
||||
@ -531,10 +514,10 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
public void onDataNotAvailable() {
|
||||
favoriteRepository.insertOrUpdateFavorite(new Favorite(
|
||||
0,
|
||||
hashtag.substring(1),
|
||||
hashtag,
|
||||
FavoriteType.HASHTAG,
|
||||
hashtagModel.getName(),
|
||||
hashtagModel.getSdProfilePic(),
|
||||
hashtagModel.getProfilePicUrl(),
|
||||
new Date()
|
||||
), new RepositoryCallback<Void>() {
|
||||
@Override
|
||||
@ -549,12 +532,12 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
});
|
||||
}
|
||||
}));
|
||||
hashtagDetailsBinding.mainHashtagImage.setImageURI(hashtagModel.getSdProfilePic());
|
||||
final String postCount = String.valueOf(hashtagModel.getPostCount());
|
||||
hashtagDetailsBinding.mainHashtagImage.setImageURI(hashtagModel.getProfilePicUrl());
|
||||
final String postCount = String.valueOf(hashtagModel.getMediaCount());
|
||||
final SpannableStringBuilder span = new SpannableStringBuilder(getResources().getQuantityString(R.plurals.main_posts_count_inline,
|
||||
hashtagModel.getPostCount() > 2000000000L
|
||||
hashtagModel.getMediaCount() > 2000000000L
|
||||
? 2000000000
|
||||
: hashtagModel.getPostCount().intValue(),
|
||||
: hashtagModel.getMediaCount().intValue(),
|
||||
postCount));
|
||||
span.setSpan(new RelativeSizeSpan(1.2f), 0, postCount.length(), 0);
|
||||
span.setSpan(new StyleSpan(Typeface.BOLD), 0, postCount.length(), 0);
|
||||
@ -602,23 +585,11 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
});
|
||||
}
|
||||
|
||||
public void stopCurrentExecutor() {
|
||||
if (currentlyExecuting != null) {
|
||||
try {
|
||||
currentlyExecuting.cancel(true);
|
||||
} catch (final Exception e) {
|
||||
// if (logCollector != null)
|
||||
// logCollector.appendException(e, LogCollector.LogFile.MAIN_HELPER, "stopCurrentExecutor");
|
||||
Log.e(TAG, "", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setTitle() {
|
||||
final ActionBar actionBar = fragmentActivity.getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
// Log.d(TAG, "setting title: " + hashtag);
|
||||
actionBar.setTitle(hashtag);
|
||||
actionBar.setTitle('#' + hashtag);
|
||||
// final Handler handler = new Handler();
|
||||
// handler.postDelayed(() -> , 1000);
|
||||
}
|
||||
|
@ -1,35 +0,0 @@
|
||||
package awais.instagrabber.models;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public final class HashtagModel implements Serializable {
|
||||
private final boolean following;
|
||||
private final long postCount;
|
||||
private final String id;
|
||||
private final String name;
|
||||
private final String sdProfilePic;
|
||||
|
||||
public HashtagModel(final String id, final String name, final String sdProfilePic, final long postCount, final boolean following) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.sdProfilePic = sdProfilePic;
|
||||
this.postCount = postCount;
|
||||
this.following = following;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getSdProfilePic() {
|
||||
return sdProfilePic;
|
||||
}
|
||||
|
||||
public Long getPostCount() { return postCount; }
|
||||
|
||||
public boolean getFollowing() { return following; }
|
||||
}
|
35
app/src/main/java/awais/instagrabber/models/enums/FollowingType.java
Executable file
35
app/src/main/java/awais/instagrabber/models/enums/FollowingType.java
Executable file
@ -0,0 +1,35 @@
|
||||
package awais.instagrabber.models.enums;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum FollowingType implements Serializable {
|
||||
@SerializedName("1")
|
||||
FOLLOWING(1),
|
||||
@SerializedName("0")
|
||||
NOT_FOLLOWING(0);
|
||||
|
||||
private final int id;
|
||||
private static final Map<Integer, FollowingType> map = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (FollowingType type : FollowingType.values()) {
|
||||
map.put(type.id, type);
|
||||
}
|
||||
}
|
||||
|
||||
FollowingType(final int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public static FollowingType valueOf(final int id) {
|
||||
return map.get(id);
|
||||
}
|
||||
}
|
@ -13,4 +13,7 @@ public interface GraphQLRepository {
|
||||
|
||||
@GET("/{username}/?__a=1")
|
||||
Call<String> getUser(@Path("username") String username);
|
||||
|
||||
@GET("/explore/tags/{tag}/?__a=1")
|
||||
Call<String> getTag(@Path("tag") String tag);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package awais.instagrabber.repositories;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import awais.instagrabber.repositories.responses.Hashtag;
|
||||
import awais.instagrabber.repositories.responses.TagFeedResponse;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.FieldMap;
|
||||
@ -13,15 +14,14 @@ import retrofit2.http.Path;
|
||||
import retrofit2.http.QueryMap;
|
||||
|
||||
public interface TagsRepository {
|
||||
@FormUrlEncoded
|
||||
@POST("/api/v1/tags/follow/{tag}/")
|
||||
Call<String> follow(@FieldMap final Map<String, String> signedForm,
|
||||
@Path("tag") String tag);
|
||||
@GET("/api/v1/tags/{tag}/info/")
|
||||
Call<Hashtag> fetch(@Path("tag") final String tag);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/api/v1/tags/unfollow/{tag}/")
|
||||
Call<String> unfollow(@FieldMap final Map<String, String> signedForm,
|
||||
@Path("tag") String tag);
|
||||
@POST("/api/v1/tags/{action}/{tag}/")
|
||||
Call<String> changeFollow(@FieldMap final Map<String, String> signedForm,
|
||||
@Path("action") String action,
|
||||
@Path("tag") String tag);
|
||||
|
||||
@GET("/api/v1/feed/tag/{tag}/")
|
||||
Call<TagFeedResponse> fetchPosts(@Path("tag") final String tag,
|
||||
|
45
app/src/main/java/awais/instagrabber/repositories/responses/Hashtag.java
Executable file
45
app/src/main/java/awais/instagrabber/repositories/responses/Hashtag.java
Executable file
@ -0,0 +1,45 @@
|
||||
package awais.instagrabber.repositories.responses;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import awais.instagrabber.models.enums.FollowingType;
|
||||
|
||||
public final class Hashtag implements Serializable {
|
||||
private final FollowingType following; // 0 false 1 true
|
||||
private final long mediaCount;
|
||||
private final String id;
|
||||
private final String name;
|
||||
private final String profilePicUrl; // on app API this is always null (property exists)
|
||||
|
||||
public Hashtag(final String id,
|
||||
final String name,
|
||||
final String profilePicUrl,
|
||||
final long mediaCount,
|
||||
final FollowingType following) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.profilePicUrl = profilePicUrl;
|
||||
this.mediaCount = mediaCount;
|
||||
this.following = following;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getProfilePicUrl() {
|
||||
return profilePicUrl;
|
||||
}
|
||||
|
||||
public Long getMediaCount() {
|
||||
return mediaCount;
|
||||
}
|
||||
|
||||
public FollowingType getFollowing() {
|
||||
return following;
|
||||
}
|
||||
}
|
@ -14,9 +14,11 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import awais.instagrabber.models.enums.FollowingType;
|
||||
import awais.instagrabber.repositories.GraphQLRepository;
|
||||
import awais.instagrabber.repositories.responses.FriendshipStatus;
|
||||
import awais.instagrabber.repositories.responses.GraphQLUserListFetchResponse;
|
||||
import awais.instagrabber.repositories.responses.Hashtag;
|
||||
import awais.instagrabber.repositories.responses.Media;
|
||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||
import awais.instagrabber.repositories.responses.User;
|
||||
@ -359,4 +361,44 @@ public class GraphQLService extends BaseService {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void fetchTag(final String tag,
|
||||
final ServiceCallback<Hashtag> callback) {
|
||||
final Call<String> request = repository.getTag(tag);
|
||||
request.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
final String rawBody = response.body();
|
||||
if (rawBody == null) {
|
||||
Log.e(TAG, "Error occurred while fetching gql tag of " + tag);
|
||||
callback.onSuccess(null);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final JSONObject body = new JSONObject(rawBody)
|
||||
.getJSONObject("graphql")
|
||||
.getJSONObject(Constants.EXTRAS_HASHTAG);
|
||||
final JSONObject timelineMedia = body.getJSONObject("edge_hashtag_to_media");
|
||||
callback.onSuccess(new Hashtag(
|
||||
body.getString(Constants.EXTRAS_ID),
|
||||
body.getString("name"),
|
||||
body.getString("profile_pic_url"),
|
||||
timelineMedia.getLong("count"),
|
||||
body.optBoolean("is_following") ? FollowingType.FOLLOWING : FollowingType.NOT_FOLLOWING));
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "onResponse", e);
|
||||
if (callback != null) {
|
||||
callback.onFailure(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
||||
if (callback != null) {
|
||||
callback.onFailure(t);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import awais.instagrabber.repositories.TagsRepository;
|
||||
import awais.instagrabber.repositories.responses.Hashtag;
|
||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||
import awais.instagrabber.repositories.responses.TagFeedResponse;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
@ -44,53 +45,39 @@ public class TagsService extends BaseService {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void follow(@NonNull final String tag,
|
||||
@NonNull final String csrfToken,
|
||||
@NonNull final long userId,
|
||||
@NonNull final String deviceUuid,
|
||||
final ServiceCallback<Boolean> callback) {
|
||||
final Map<String, Object> form = new HashMap<>(3);
|
||||
form.put("_csrftoken", csrfToken);
|
||||
form.put("_uid", userId);
|
||||
form.put("_uuid", deviceUuid);
|
||||
final Map<String, String> signedForm = Utils.sign(form);
|
||||
final Call<String> request = repository.follow(signedForm, tag);
|
||||
request.enqueue(new Callback<String>() {
|
||||
public void fetch(@NonNull final String tag,
|
||||
final ServiceCallback<Hashtag> callback) {
|
||||
final Call<Hashtag> request = repository.fetch(tag);
|
||||
request.enqueue(new Callback<Hashtag>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
final String body = response.body();
|
||||
if (body == null) {
|
||||
callback.onFailure(new RuntimeException("body is null"));
|
||||
public void onResponse(@NonNull final Call<Hashtag> call, @NonNull final Response<Hashtag> response) {
|
||||
if (callback == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final JSONObject jsonObject = new JSONObject(body);
|
||||
final String status = jsonObject.optString("status");
|
||||
callback.onSuccess(status.equals("ok"));
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "onResponse: ", e);
|
||||
}
|
||||
callback.onSuccess(response.body());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
||||
// Log.e(TAG, "onFailure: ", t);
|
||||
callback.onFailure(t);
|
||||
public void onFailure(@NonNull final Call<Hashtag> call, @NonNull final Throwable t) {
|
||||
if (callback != null) {
|
||||
callback.onFailure(t);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void unfollow(@NonNull final String tag,
|
||||
@NonNull final String csrfToken,
|
||||
@NonNull final long userId,
|
||||
@NonNull final String deviceUuid,
|
||||
final ServiceCallback<Boolean> callback) {
|
||||
public void changeFollow(@NonNull final String action,
|
||||
@NonNull final String tag,
|
||||
@NonNull final String csrfToken,
|
||||
@NonNull final long userId,
|
||||
@NonNull final String deviceUuid,
|
||||
final ServiceCallback<Boolean> callback) {
|
||||
final Map<String, Object> form = new HashMap<>(3);
|
||||
form.put("_csrftoken", csrfToken);
|
||||
form.put("_uid", userId);
|
||||
form.put("_uuid", deviceUuid);
|
||||
final Map<String, String> signedForm = Utils.sign(form);
|
||||
final Call<String> request = repository.unfollow(signedForm, tag);
|
||||
final Call<String> request = repository.changeFollow(signedForm, action, tag);
|
||||
request.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
||||
|
Loading…
Reference in New Issue
Block a user