mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-24 23:57:30 +00:00
convert profile backend stuff to kotlin
This commit is contained in:
parent
8c3ec92649
commit
77bca1b8ec
@ -9,13 +9,14 @@ import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
|||||||
import awais.instagrabber.repositories.responses.User;
|
import awais.instagrabber.repositories.responses.User;
|
||||||
import awais.instagrabber.utils.CoroutineUtilsKt;
|
import awais.instagrabber.utils.CoroutineUtilsKt;
|
||||||
import awais.instagrabber.webservices.GraphQLRepository;
|
import awais.instagrabber.webservices.GraphQLRepository;
|
||||||
import awais.instagrabber.webservices.ProfileService;
|
import awais.instagrabber.webservices.ProfileRepository;
|
||||||
import awais.instagrabber.webservices.ServiceCallback;
|
import awais.instagrabber.webservices.ServiceCallback;
|
||||||
|
import kotlin.coroutines.Continuation;
|
||||||
import kotlinx.coroutines.Dispatchers;
|
import kotlinx.coroutines.Dispatchers;
|
||||||
|
|
||||||
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 ProfileRepository profileRepository;
|
||||||
private final GraphQLRepository graphQLRepository;
|
private final GraphQLRepository graphQLRepository;
|
||||||
private final User profileModel;
|
private final User profileModel;
|
||||||
private final boolean isLoggedIn;
|
private final boolean isLoggedIn;
|
||||||
@ -26,43 +27,32 @@ public class ProfilePostFetchService implements PostFetcher.PostFetchService {
|
|||||||
this.profileModel = profileModel;
|
this.profileModel = profileModel;
|
||||||
this.isLoggedIn = isLoggedIn;
|
this.isLoggedIn = isLoggedIn;
|
||||||
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
|
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
|
||||||
profileService = isLoggedIn ? ProfileService.getInstance() : null;
|
profileRepository = isLoggedIn ? ProfileRepository.Companion.getInstance() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fetch(final FetchListener<List<Media>> fetchListener) {
|
public void fetch(final FetchListener<List<Media>> fetchListener) {
|
||||||
final ServiceCallback<PostsFetchResponse> cb = new ServiceCallback<PostsFetchResponse>() {
|
final Continuation<PostsFetchResponse> cb = CoroutineUtilsKt.getContinuation((result, t) -> {
|
||||||
@Override
|
if (t != null) {
|
||||||
public void onSuccess(final PostsFetchResponse result) {
|
|
||||||
if (result == null) return;
|
|
||||||
nextMaxId = result.getNextCursor();
|
|
||||||
moreAvailable = result.getHasNextPage();
|
|
||||||
if (fetchListener != null) {
|
|
||||||
fetchListener.onResult(result.getFeedModels());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(final Throwable t) {
|
|
||||||
// Log.e(TAG, "onFailure: ", t);
|
|
||||||
if (fetchListener != null) {
|
if (fetchListener != null) {
|
||||||
fetchListener.onFailure(t);
|
fetchListener.onFailure(t);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
};
|
if (result == null) return;
|
||||||
if (isLoggedIn) profileService.fetchPosts(profileModel.getPk(), nextMaxId, cb);
|
nextMaxId = result.getNextCursor();
|
||||||
|
moreAvailable = result.getHasNextPage();
|
||||||
|
if (fetchListener != null) {
|
||||||
|
fetchListener.onResult(result.getFeedModels());
|
||||||
|
}
|
||||||
|
}, Dispatchers.getIO());
|
||||||
|
if (isLoggedIn) profileRepository.fetchPosts(profileModel.getPk(), nextMaxId, cb);
|
||||||
else graphQLRepository.fetchProfilePosts(
|
else graphQLRepository.fetchProfilePosts(
|
||||||
profileModel.getPk(),
|
profileModel.getPk(),
|
||||||
30,
|
30,
|
||||||
nextMaxId,
|
nextMaxId,
|
||||||
profileModel,
|
profileModel,
|
||||||
CoroutineUtilsKt.getContinuation((postsFetchResponse, throwable) -> {
|
cb
|
||||||
if (throwable != null) {
|
|
||||||
cb.onFailure(throwable);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cb.onSuccess(postsFetchResponse);
|
|
||||||
}, Dispatchers.getIO())
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,12 +9,12 @@ import awais.instagrabber.repositories.responses.Media;
|
|||||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
||||||
import awais.instagrabber.utils.CoroutineUtilsKt;
|
import awais.instagrabber.utils.CoroutineUtilsKt;
|
||||||
import awais.instagrabber.webservices.GraphQLRepository;
|
import awais.instagrabber.webservices.GraphQLRepository;
|
||||||
import awais.instagrabber.webservices.ProfileService;
|
import awais.instagrabber.webservices.ProfileRepository;
|
||||||
import awais.instagrabber.webservices.ServiceCallback;
|
import kotlin.coroutines.Continuation;
|
||||||
import kotlinx.coroutines.Dispatchers;
|
import kotlinx.coroutines.Dispatchers;
|
||||||
|
|
||||||
public class SavedPostFetchService implements PostFetcher.PostFetchService {
|
public class SavedPostFetchService implements PostFetcher.PostFetchService {
|
||||||
private final ProfileService profileService;
|
private final ProfileRepository profileRepository;
|
||||||
private final GraphQLRepository graphQLRepository;
|
private final GraphQLRepository graphQLRepository;
|
||||||
private final long profileId;
|
private final long profileId;
|
||||||
private final PostItemType type;
|
private final PostItemType type;
|
||||||
@ -30,55 +30,42 @@ public class SavedPostFetchService implements PostFetcher.PostFetchService {
|
|||||||
this.isLoggedIn = isLoggedIn;
|
this.isLoggedIn = isLoggedIn;
|
||||||
this.collectionId = collectionId;
|
this.collectionId = collectionId;
|
||||||
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
|
graphQLRepository = isLoggedIn ? null : GraphQLRepository.Companion.getInstance();
|
||||||
profileService = isLoggedIn ? ProfileService.getInstance() : null;
|
profileRepository = isLoggedIn ? ProfileRepository.Companion.getInstance() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fetch(final FetchListener<List<Media>> fetchListener) {
|
public void fetch(final FetchListener<List<Media>> fetchListener) {
|
||||||
final ServiceCallback<PostsFetchResponse> callback = new ServiceCallback<PostsFetchResponse>() {
|
final Continuation<PostsFetchResponse> callback = CoroutineUtilsKt.getContinuation((result, t) -> {
|
||||||
@Override
|
if (t != null) {
|
||||||
public void onSuccess(final PostsFetchResponse result) {
|
|
||||||
if (result == null) return;
|
|
||||||
nextMaxId = result.getNextCursor();
|
|
||||||
moreAvailable = result.getHasNextPage();
|
|
||||||
if (fetchListener != null) {
|
|
||||||
fetchListener.onResult(result.getFeedModels());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(final Throwable t) {
|
|
||||||
// Log.e(TAG, "onFailure: ", t);
|
|
||||||
if (fetchListener != null) {
|
if (fetchListener != null) {
|
||||||
fetchListener.onFailure(t);
|
fetchListener.onFailure(t);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
};
|
if (result == null) return;
|
||||||
|
nextMaxId = result.getNextCursor();
|
||||||
|
moreAvailable = result.getHasNextPage();
|
||||||
|
if (fetchListener != null) {
|
||||||
|
fetchListener.onResult(result.getFeedModels());
|
||||||
|
}
|
||||||
|
}, Dispatchers.getIO());
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case LIKED:
|
case LIKED:
|
||||||
profileService.fetchLiked(nextMaxId, callback);
|
profileRepository.fetchLiked(nextMaxId, callback);
|
||||||
break;
|
break;
|
||||||
case TAGGED:
|
case TAGGED:
|
||||||
if (isLoggedIn) profileService.fetchTagged(profileId, nextMaxId, callback);
|
if (isLoggedIn) profileRepository.fetchTagged(profileId, nextMaxId, callback);
|
||||||
else graphQLRepository.fetchTaggedPosts(
|
else graphQLRepository.fetchTaggedPosts(
|
||||||
profileId,
|
profileId,
|
||||||
30,
|
30,
|
||||||
nextMaxId,
|
nextMaxId,
|
||||||
CoroutineUtilsKt.getContinuation((postsFetchResponse, throwable) -> {
|
callback
|
||||||
if (throwable != null) {
|
|
||||||
callback.onFailure(throwable);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback.onSuccess(postsFetchResponse);
|
|
||||||
}, Dispatchers.getIO())
|
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case COLLECTION:
|
case COLLECTION:
|
||||||
case SAVED:
|
case SAVED:
|
||||||
profileService.fetchSaved(nextMaxId, collectionId, callback);
|
profileRepository.fetchSaved(nextMaxId, collectionId, callback);
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
callback.onFailure(null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,9 +34,10 @@ import awais.instagrabber.databinding.FragmentSavedCollectionsBinding;
|
|||||||
import awais.instagrabber.repositories.responses.saved.CollectionsListResponse;
|
import awais.instagrabber.repositories.responses.saved.CollectionsListResponse;
|
||||||
import awais.instagrabber.utils.Constants;
|
import awais.instagrabber.utils.Constants;
|
||||||
import awais.instagrabber.utils.CookieUtils;
|
import awais.instagrabber.utils.CookieUtils;
|
||||||
|
import awais.instagrabber.utils.CoroutineUtilsKt;
|
||||||
import awais.instagrabber.utils.Utils;
|
import awais.instagrabber.utils.Utils;
|
||||||
import awais.instagrabber.viewmodels.SavedCollectionsViewModel;
|
import awais.instagrabber.viewmodels.SavedCollectionsViewModel;
|
||||||
import awais.instagrabber.webservices.ProfileService;
|
import awais.instagrabber.webservices.ProfileRepository;
|
||||||
import awais.instagrabber.webservices.ServiceCallback;
|
import awais.instagrabber.webservices.ServiceCallback;
|
||||||
|
|
||||||
import static awais.instagrabber.utils.Utils.settingsHelper;
|
import static awais.instagrabber.utils.Utils.settingsHelper;
|
||||||
@ -51,14 +52,14 @@ public class SavedCollectionsFragment extends Fragment implements SwipeRefreshLa
|
|||||||
private SavedCollectionsViewModel savedCollectionsViewModel;
|
private SavedCollectionsViewModel savedCollectionsViewModel;
|
||||||
private boolean shouldRefresh = true;
|
private boolean shouldRefresh = true;
|
||||||
private boolean isSaving;
|
private boolean isSaving;
|
||||||
private ProfileService profileService;
|
private ProfileRepository profileRepository;
|
||||||
private SavedCollectionsAdapter adapter;
|
private SavedCollectionsAdapter adapter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
fragmentActivity = (MainActivity) requireActivity();
|
fragmentActivity = (MainActivity) requireActivity();
|
||||||
profileService = ProfileService.getInstance();
|
profileRepository = ProfileRepository.Companion.getInstance();
|
||||||
savedCollectionsViewModel = new ViewModelProvider(fragmentActivity).get(SavedCollectionsViewModel.class);
|
savedCollectionsViewModel = new ViewModelProvider(fragmentActivity).get(SavedCollectionsViewModel.class);
|
||||||
setHasOptionsMenu(true);
|
setHasOptionsMenu(true);
|
||||||
}
|
}
|
||||||
@ -106,23 +107,20 @@ public class SavedCollectionsFragment extends Fragment implements SwipeRefreshLa
|
|||||||
.setView(input)
|
.setView(input)
|
||||||
.setPositiveButton(R.string.confirm, (d, w) -> {
|
.setPositiveButton(R.string.confirm, (d, w) -> {
|
||||||
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
final String cookie = settingsHelper.getString(Constants.COOKIE);
|
||||||
profileService.createCollection(
|
profileRepository.createCollection(
|
||||||
input.getText().toString(),
|
input.getText().toString(),
|
||||||
settingsHelper.getString(Constants.DEVICE_UUID),
|
settingsHelper.getString(Constants.DEVICE_UUID),
|
||||||
CookieUtils.getUserIdFromCookie(cookie),
|
CookieUtils.getUserIdFromCookie(cookie),
|
||||||
CookieUtils.getCsrfTokenFromCookie(cookie),
|
CookieUtils.getCsrfTokenFromCookie(cookie),
|
||||||
new ServiceCallback<String>() {
|
CoroutineUtilsKt.getContinuation((result, t) -> {
|
||||||
@Override
|
if (t != null) {
|
||||||
public void onSuccess(final String result) {
|
|
||||||
onRefresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(final Throwable t) {
|
|
||||||
Log.e(TAG, "Error creating collection", t);
|
Log.e(TAG, "Error creating collection", t);
|
||||||
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
onRefresh();
|
||||||
|
})
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
.show();
|
.show();
|
||||||
@ -174,20 +172,16 @@ public class SavedCollectionsFragment extends Fragment implements SwipeRefreshLa
|
|||||||
|
|
||||||
private void fetchTopics(final String maxId) {
|
private void fetchTopics(final String maxId) {
|
||||||
binding.swipeRefreshLayout.setRefreshing(true);
|
binding.swipeRefreshLayout.setRefreshing(true);
|
||||||
profileService.fetchCollections(maxId, new ServiceCallback<CollectionsListResponse>() {
|
profileRepository.fetchCollections(maxId, CoroutineUtilsKt.getContinuation((result, t) -> {
|
||||||
@Override
|
if (t != null) {
|
||||||
public void onSuccess(final CollectionsListResponse result) {
|
|
||||||
if (result == null) return;
|
|
||||||
savedCollectionsViewModel.getList().postValue(result.getItems());
|
|
||||||
binding.swipeRefreshLayout.setRefreshing(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(final Throwable t) {
|
|
||||||
Log.e(TAG, "onFailure", t);
|
Log.e(TAG, "onFailure", t);
|
||||||
binding.swipeRefreshLayout.setRefreshing(false);
|
binding.swipeRefreshLayout.setRefreshing(false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
if (result == null) return;
|
||||||
|
savedCollectionsViewModel.getList().postValue(result.getItems());
|
||||||
|
binding.swipeRefreshLayout.setRefreshing(false);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setNavControllerResult(@NonNull final NavController navController, final String result) {
|
private void setNavControllerResult(@NonNull final NavController navController, final String result) {
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
package awais.instagrabber.repositories;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import awais.instagrabber.repositories.responses.WrappedFeedResponse;
|
|
||||||
import awais.instagrabber.repositories.responses.saved.CollectionsListResponse;
|
|
||||||
import awais.instagrabber.repositories.responses.UserFeedResponse;
|
|
||||||
import retrofit2.Call;
|
|
||||||
import retrofit2.http.FieldMap;
|
|
||||||
import retrofit2.http.FormUrlEncoded;
|
|
||||||
import retrofit2.http.GET;
|
|
||||||
import retrofit2.http.Path;
|
|
||||||
import retrofit2.http.POST;
|
|
||||||
import retrofit2.http.QueryMap;
|
|
||||||
|
|
||||||
public interface ProfileRepository {
|
|
||||||
|
|
||||||
@GET("/api/v1/feed/user/{uid}/")
|
|
||||||
Call<UserFeedResponse> fetch(@Path("uid") final long uid, @QueryMap Map<String, String> queryParams);
|
|
||||||
|
|
||||||
@GET("/api/v1/feed/saved/")
|
|
||||||
Call<WrappedFeedResponse> fetchSaved(@QueryMap Map<String, String> queryParams);
|
|
||||||
|
|
||||||
@GET("/api/v1/feed/collection/{collectionId}/")
|
|
||||||
Call<WrappedFeedResponse> fetchSavedCollection(@Path("collectionId") final String collectionId,
|
|
||||||
@QueryMap Map<String, String> queryParams);
|
|
||||||
|
|
||||||
@GET("/api/v1/feed/liked/")
|
|
||||||
Call<UserFeedResponse> fetchLiked(@QueryMap Map<String, String> queryParams);
|
|
||||||
|
|
||||||
@GET("/api/v1/usertags/{profileId}/feed/")
|
|
||||||
Call<UserFeedResponse> fetchTagged(@Path("profileId") final long profileId, @QueryMap Map<String, String> queryParams);
|
|
||||||
|
|
||||||
@GET("/api/v1/collections/list/")
|
|
||||||
Call<CollectionsListResponse> fetchCollections(@QueryMap Map<String, String> queryParams);
|
|
||||||
|
|
||||||
@FormUrlEncoded
|
|
||||||
@POST("/api/v1/collections/create/")
|
|
||||||
Call<String> createCollection(@FieldMap Map<String, String> signedForm);
|
|
||||||
}
|
|
@ -0,0 +1,40 @@
|
|||||||
|
package awais.instagrabber.repositories
|
||||||
|
|
||||||
|
import awais.instagrabber.repositories.responses.UserFeedResponse
|
||||||
|
import awais.instagrabber.repositories.responses.WrappedFeedResponse
|
||||||
|
import awais.instagrabber.repositories.responses.saved.CollectionsListResponse
|
||||||
|
import retrofit2.Call
|
||||||
|
import retrofit2.http.*
|
||||||
|
|
||||||
|
interface ProfileService {
|
||||||
|
@GET("/api/v1/feed/user/{uid}/")
|
||||||
|
suspend fun fetch(
|
||||||
|
@Path("uid") uid: Long,
|
||||||
|
@QueryMap queryParams: Map<String?, String?>?
|
||||||
|
): UserFeedResponse?
|
||||||
|
|
||||||
|
@GET("/api/v1/feed/saved/")
|
||||||
|
suspend fun fetchSaved(@QueryMap queryParams: Map<String?, String?>?): WrappedFeedResponse?
|
||||||
|
|
||||||
|
@GET("/api/v1/feed/collection/{collectionId}/")
|
||||||
|
suspend fun fetchSavedCollection(
|
||||||
|
@Path("collectionId") collectionId: String?,
|
||||||
|
@QueryMap queryParams: Map<String?, String?>?
|
||||||
|
): WrappedFeedResponse?
|
||||||
|
|
||||||
|
@GET("/api/v1/feed/liked/")
|
||||||
|
suspend fun fetchLiked(@QueryMap queryParams: Map<String?, String?>?): UserFeedResponse?
|
||||||
|
|
||||||
|
@GET("/api/v1/usertags/{profileId}/feed/")
|
||||||
|
suspend fun fetchTagged(
|
||||||
|
@Path("profileId") profileId: Long,
|
||||||
|
@QueryMap queryParams: Map<String?, String?>?
|
||||||
|
): UserFeedResponse?
|
||||||
|
|
||||||
|
@GET("/api/v1/collections/list/")
|
||||||
|
suspend fun fetchCollections(@QueryMap queryParams: Map<String?, String?>?): CollectionsListResponse?
|
||||||
|
|
||||||
|
@FormUrlEncoded
|
||||||
|
@POST("/api/v1/collections/create/")
|
||||||
|
suspend fun createCollection(@FieldMap signedForm: Map<String?, String?>?): String?
|
||||||
|
}
|
@ -18,7 +18,7 @@ import retrofit2.Callback;
|
|||||||
import retrofit2.Response;
|
import retrofit2.Response;
|
||||||
|
|
||||||
public class CollectionService {
|
public class CollectionService {
|
||||||
private static final String TAG = "ProfileService";
|
private static final String TAG = "CollectionService";
|
||||||
|
|
||||||
private final CollectionRepository repository;
|
private final CollectionRepository repository;
|
||||||
private final String deviceUuid, csrfToken;
|
private final String deviceUuid, csrfToken;
|
||||||
|
@ -0,0 +1,121 @@
|
|||||||
|
package awais.instagrabber.webservices
|
||||||
|
|
||||||
|
import awais.instagrabber.repositories.ProfileService
|
||||||
|
import awais.instagrabber.repositories.responses.Media
|
||||||
|
import awais.instagrabber.repositories.responses.PostsFetchResponse
|
||||||
|
import awais.instagrabber.repositories.responses.WrappedMedia
|
||||||
|
import awais.instagrabber.repositories.responses.saved.CollectionsListResponse
|
||||||
|
import awais.instagrabber.utils.Utils
|
||||||
|
import com.google.common.collect.ImmutableMap
|
||||||
|
import java.util.*
|
||||||
|
import java.util.stream.Collectors
|
||||||
|
|
||||||
|
class ProfileRepository private constructor(private val repository: ProfileService) {
|
||||||
|
suspend fun fetchPosts(
|
||||||
|
userId: Long,
|
||||||
|
maxId: String?
|
||||||
|
): PostsFetchResponse? {
|
||||||
|
val builder = ImmutableMap.builder<String?, String?>()
|
||||||
|
if (!maxId.isNullOrEmpty()) {
|
||||||
|
builder.put("max_id", maxId)
|
||||||
|
}
|
||||||
|
val body = repository.fetch(userId, builder.build()) ?: return null
|
||||||
|
return PostsFetchResponse(
|
||||||
|
body.items,
|
||||||
|
body.moreAvailable,
|
||||||
|
body.nextMaxId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun fetchSaved(maxId: String?, collectionId: String): PostsFetchResponse? {
|
||||||
|
val builder = ImmutableMap.builder<String?, String?>()
|
||||||
|
if (!maxId.isNullOrEmpty()) {
|
||||||
|
builder.put("max_id", maxId)
|
||||||
|
}
|
||||||
|
val userFeedResponse = if (collectionId.isNullOrEmpty() || collectionId == "ALL_MEDIA_AUTO_COLLECTION")
|
||||||
|
(repository.fetchSaved(builder.build()) ?: return null)
|
||||||
|
else repository.fetchSavedCollection(collectionId, builder.build()) ?: return null
|
||||||
|
val items = userFeedResponse.items
|
||||||
|
val posts: List<Media> = if (items == null) {
|
||||||
|
emptyList()
|
||||||
|
} else {
|
||||||
|
items.stream()
|
||||||
|
.map(WrappedMedia::media)
|
||||||
|
.filter { obj: Media? -> Objects.nonNull(obj) }
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
}
|
||||||
|
return PostsFetchResponse(
|
||||||
|
posts,
|
||||||
|
userFeedResponse.isMoreAvailable,
|
||||||
|
userFeedResponse.nextMaxId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun fetchCollections(maxId: String?): CollectionsListResponse? {
|
||||||
|
val builder = ImmutableMap.builder<String?, String?>()
|
||||||
|
if (!maxId.isNullOrEmpty()) {
|
||||||
|
builder.put("max_id", maxId)
|
||||||
|
}
|
||||||
|
builder.put(
|
||||||
|
"collection_types",
|
||||||
|
"[\"ALL_MEDIA_AUTO_COLLECTION\",\"MEDIA\",\"PRODUCT_AUTO_COLLECTION\"]"
|
||||||
|
)
|
||||||
|
return repository.fetchCollections(builder.build())
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun createCollection(
|
||||||
|
name: String,
|
||||||
|
deviceUuid: String,
|
||||||
|
userId: Long,
|
||||||
|
csrfToken: String
|
||||||
|
): String? {
|
||||||
|
val form: MutableMap<String, Any> = HashMap(6)
|
||||||
|
form["_csrftoken"] = csrfToken
|
||||||
|
form["_uuid"] = deviceUuid
|
||||||
|
form["_uid"] = userId
|
||||||
|
form["collection_visibility"] =
|
||||||
|
"0" // 1 for public, planned for future but currently inexistant
|
||||||
|
form["module_name"] = "collection_create"
|
||||||
|
form["name"] = name
|
||||||
|
val signedForm = Utils.sign(form)
|
||||||
|
return repository.createCollection(signedForm)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun fetchLiked(maxId: String?): PostsFetchResponse? {
|
||||||
|
val builder = ImmutableMap.builder<String?, String?>()
|
||||||
|
if (!maxId.isNullOrEmpty()) {
|
||||||
|
builder.put("max_id", maxId)
|
||||||
|
}
|
||||||
|
val userFeedResponse = repository.fetchLiked(builder.build()) ?: return null
|
||||||
|
return PostsFetchResponse(
|
||||||
|
userFeedResponse.items,
|
||||||
|
userFeedResponse.moreAvailable,
|
||||||
|
userFeedResponse.nextMaxId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun fetchTagged(profileId: Long, maxId: String?): PostsFetchResponse? {
|
||||||
|
val builder = ImmutableMap.builder<String?, String?>()
|
||||||
|
if (!maxId.isNullOrEmpty()) {
|
||||||
|
builder.put("max_id", maxId)
|
||||||
|
}
|
||||||
|
val userFeedResponse = repository.fetchTagged(profileId, builder.build()) ?: return null
|
||||||
|
return PostsFetchResponse(
|
||||||
|
userFeedResponse.items,
|
||||||
|
userFeedResponse.moreAvailable,
|
||||||
|
userFeedResponse.nextMaxId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@Volatile
|
||||||
|
private var INSTANCE: ProfileRepository? = null
|
||||||
|
|
||||||
|
fun getInstance(): ProfileRepository {
|
||||||
|
return INSTANCE ?: synchronized(this) {
|
||||||
|
val service: ProfileService = RetrofitFactory.retrofit.create(ProfileService::class.java)
|
||||||
|
ProfileRepository(service).also { INSTANCE = it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,299 +0,0 @@
|
|||||||
package awais.instagrabber.webservices;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import awais.instagrabber.repositories.ProfileRepository;
|
|
||||||
import awais.instagrabber.repositories.responses.Media;
|
|
||||||
import awais.instagrabber.repositories.responses.PostsFetchResponse;
|
|
||||||
import awais.instagrabber.repositories.responses.UserFeedResponse;
|
|
||||||
import awais.instagrabber.repositories.responses.WrappedFeedResponse;
|
|
||||||
import awais.instagrabber.repositories.responses.WrappedMedia;
|
|
||||||
import awais.instagrabber.repositories.responses.saved.CollectionsListResponse;
|
|
||||||
import awais.instagrabber.utils.TextUtils;
|
|
||||||
import awais.instagrabber.utils.Utils;
|
|
||||||
import retrofit2.Call;
|
|
||||||
import retrofit2.Callback;
|
|
||||||
import retrofit2.Response;
|
|
||||||
|
|
||||||
public class ProfileService {
|
|
||||||
private static final String TAG = "ProfileService";
|
|
||||||
|
|
||||||
private final ProfileRepository repository;
|
|
||||||
|
|
||||||
private static ProfileService instance;
|
|
||||||
|
|
||||||
private ProfileService() {
|
|
||||||
repository = RetrofitFactory.INSTANCE
|
|
||||||
.getRetrofit()
|
|
||||||
.create(ProfileRepository.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProfileService getInstance() {
|
|
||||||
if (instance == null) {
|
|
||||||
instance = new ProfileService();
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fetchPosts(final long userId,
|
|
||||||
final String maxId,
|
|
||||||
final ServiceCallback<PostsFetchResponse> callback) {
|
|
||||||
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
|
||||||
if (!TextUtils.isEmpty(maxId)) {
|
|
||||||
builder.put("max_id", maxId);
|
|
||||||
}
|
|
||||||
final Call<UserFeedResponse> request = repository.fetch(userId, builder.build());
|
|
||||||
request.enqueue(new Callback<UserFeedResponse>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(@NonNull final Call<UserFeedResponse> call, @NonNull final Response<UserFeedResponse> response) {
|
|
||||||
if (callback == null) return;
|
|
||||||
final UserFeedResponse body = response.body();
|
|
||||||
if (body == null) {
|
|
||||||
callback.onSuccess(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback.onSuccess(new PostsFetchResponse(
|
|
||||||
body.getItems(),
|
|
||||||
body.getMoreAvailable(),
|
|
||||||
body.getNextMaxId()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull final Call<UserFeedResponse> call, @NonNull final Throwable t) {
|
|
||||||
if (callback != null) {
|
|
||||||
callback.onFailure(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fetchSaved(final String maxId,
|
|
||||||
final String collectionId,
|
|
||||||
final ServiceCallback<PostsFetchResponse> callback) {
|
|
||||||
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
|
||||||
Call<WrappedFeedResponse> request = null;
|
|
||||||
if (!TextUtils.isEmpty(maxId)) {
|
|
||||||
builder.put("max_id", maxId);
|
|
||||||
}
|
|
||||||
if (TextUtils.isEmpty(collectionId) || collectionId.equals("ALL_MEDIA_AUTO_COLLECTION")) request = repository.fetchSaved(builder.build());
|
|
||||||
else request = repository.fetchSavedCollection(collectionId, builder.build());
|
|
||||||
request.enqueue(new Callback<WrappedFeedResponse>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(@NonNull final Call<WrappedFeedResponse> call, @NonNull final Response<WrappedFeedResponse> response) {
|
|
||||||
if (callback == null) return;
|
|
||||||
final WrappedFeedResponse userFeedResponse = response.body();
|
|
||||||
if (userFeedResponse == null) {
|
|
||||||
callback.onSuccess(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final List<WrappedMedia> items = userFeedResponse.getItems();
|
|
||||||
final List<Media> posts;
|
|
||||||
if (items == null) {
|
|
||||||
posts = Collections.emptyList();
|
|
||||||
} else {
|
|
||||||
posts = items.stream()
|
|
||||||
.map(WrappedMedia::getMedia)
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
callback.onSuccess(new PostsFetchResponse(
|
|
||||||
posts,
|
|
||||||
userFeedResponse.isMoreAvailable(),
|
|
||||||
userFeedResponse.getNextMaxId()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull final Call<WrappedFeedResponse> call, @NonNull final Throwable t) {
|
|
||||||
if (callback != null) {
|
|
||||||
callback.onFailure(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fetchCollections(final String maxId,
|
|
||||||
final ServiceCallback<CollectionsListResponse> callback) {
|
|
||||||
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
|
||||||
if (!TextUtils.isEmpty(maxId)) {
|
|
||||||
builder.put("max_id", maxId);
|
|
||||||
}
|
|
||||||
builder.put("collection_types", "[\"ALL_MEDIA_AUTO_COLLECTION\",\"MEDIA\",\"PRODUCT_AUTO_COLLECTION\"]");
|
|
||||||
final Call<CollectionsListResponse> request = repository.fetchCollections(builder.build());
|
|
||||||
request.enqueue(new Callback<CollectionsListResponse>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(@NonNull final Call<CollectionsListResponse> call, @NonNull final Response<CollectionsListResponse> response) {
|
|
||||||
if (callback == null) return;
|
|
||||||
final CollectionsListResponse collectionsListResponse = response.body();
|
|
||||||
if (collectionsListResponse == null) {
|
|
||||||
callback.onSuccess(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback.onSuccess(collectionsListResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull final Call<CollectionsListResponse> call, @NonNull final Throwable t) {
|
|
||||||
if (callback != null) {
|
|
||||||
callback.onFailure(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void createCollection(final String name,
|
|
||||||
final String deviceUuid,
|
|
||||||
final long userId,
|
|
||||||
final String csrfToken,
|
|
||||||
final ServiceCallback<String> callback) {
|
|
||||||
final Map<String, Object> form = new HashMap<>(6);
|
|
||||||
form.put("_csrftoken", csrfToken);
|
|
||||||
form.put("_uuid", deviceUuid);
|
|
||||||
form.put("_uid", userId);
|
|
||||||
form.put("collection_visibility", "0"); // 1 for public, planned for future but currently inexistant
|
|
||||||
form.put("module_name", "collection_create");
|
|
||||||
form.put("name", name);
|
|
||||||
final Map<String, String> signedForm = Utils.sign(form);
|
|
||||||
final Call<String> request = repository.createCollection(signedForm);
|
|
||||||
request.enqueue(new Callback<String>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(@NonNull final Call<String> call, @NonNull final Response<String> response) {
|
|
||||||
if (callback == null) return;
|
|
||||||
final String collectionsListResponse = response.body();
|
|
||||||
if (collectionsListResponse == null) {
|
|
||||||
callback.onSuccess(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback.onSuccess(collectionsListResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) {
|
|
||||||
if (callback != null) {
|
|
||||||
callback.onFailure(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fetchLiked(final String maxId,
|
|
||||||
final ServiceCallback<PostsFetchResponse> callback) {
|
|
||||||
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
|
||||||
if (!TextUtils.isEmpty(maxId)) {
|
|
||||||
builder.put("max_id", maxId);
|
|
||||||
}
|
|
||||||
final Call<UserFeedResponse> request = repository.fetchLiked(builder.build());
|
|
||||||
request.enqueue(new Callback<UserFeedResponse>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(@NonNull final Call<UserFeedResponse> call, @NonNull final Response<UserFeedResponse> response) {
|
|
||||||
if (callback == null) return;
|
|
||||||
final UserFeedResponse userFeedResponse = response.body();
|
|
||||||
if (userFeedResponse == null) {
|
|
||||||
callback.onSuccess(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback.onSuccess(new PostsFetchResponse(
|
|
||||||
userFeedResponse.getItems(),
|
|
||||||
userFeedResponse.getMoreAvailable(),
|
|
||||||
userFeedResponse.getNextMaxId()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull final Call<UserFeedResponse> call, @NonNull final Throwable t) {
|
|
||||||
if (callback != null) {
|
|
||||||
callback.onFailure(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fetchTagged(final long profileId,
|
|
||||||
final String maxId,
|
|
||||||
final ServiceCallback<PostsFetchResponse> callback) {
|
|
||||||
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
|
||||||
if (!TextUtils.isEmpty(maxId)) {
|
|
||||||
builder.put("max_id", maxId);
|
|
||||||
}
|
|
||||||
final Call<UserFeedResponse> request = repository.fetchTagged(profileId, builder.build());
|
|
||||||
request.enqueue(new Callback<UserFeedResponse>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(@NonNull final Call<UserFeedResponse> call, @NonNull final Response<UserFeedResponse> response) {
|
|
||||||
if (callback == null) return;
|
|
||||||
final UserFeedResponse userFeedResponse = response.body();
|
|
||||||
if (userFeedResponse == null) {
|
|
||||||
callback.onSuccess(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback.onSuccess(new PostsFetchResponse(
|
|
||||||
userFeedResponse.getItems(),
|
|
||||||
userFeedResponse.getMoreAvailable(),
|
|
||||||
userFeedResponse.getNextMaxId()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NonNull final Call<UserFeedResponse> call, @NonNull final Throwable t) {
|
|
||||||
if (callback != null) {
|
|
||||||
callback.onFailure(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// private PostsFetchResponse parseProfilePostsResponse(final String body) throws JSONException {
|
|
||||||
// final JSONObject root = new JSONObject(body);
|
|
||||||
// final boolean moreAvailable = root.optBoolean("more_available");
|
|
||||||
// final String nextMaxId = root.optString("next_max_id");
|
|
||||||
// final JSONArray itemsJson = root.optJSONArray("items");
|
|
||||||
// final List<FeedModel> items = parseItems(itemsJson, false);
|
|
||||||
// return new PostsFetchResponse(
|
|
||||||
// items,
|
|
||||||
// moreAvailable,
|
|
||||||
// nextMaxId
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private PostsFetchResponse parseSavedPostsResponse(final String body, final boolean isInMedia) throws JSONException {
|
|
||||||
// final JSONObject root = new JSONObject(body);
|
|
||||||
// final boolean moreAvailable = root.optBoolean("more_available");
|
|
||||||
// final String nextMaxId = root.optString("next_max_id");
|
|
||||||
// final int numResults = root.optInt("num_results");
|
|
||||||
// final String status = root.optString("status");
|
|
||||||
// final JSONArray itemsJson = root.optJSONArray("items");
|
|
||||||
// final List<FeedModel> items = parseItems(itemsJson, isInMedia);
|
|
||||||
// return new PostsFetchResponse(
|
|
||||||
// items,
|
|
||||||
// moreAvailable,
|
|
||||||
// nextMaxId
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private List<FeedModel> parseItems(final JSONArray items, final boolean isInMedia) 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.parseItem(isInMedia ? itemJson.optJSONObject("media") : itemJson);
|
|
||||||
// if (feedModel != null) {
|
|
||||||
// feedModels.add(feedModel);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return feedModels;
|
|
||||||
// }
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user