Browse Source
Convert MediaRepository and MediaService to kotlin.
renovate/org.robolectric-robolectric-4.x
Convert MediaRepository and MediaService to kotlin.
renovate/org.robolectric-robolectric-4.x
Ammar Githam
4 years ago
14 changed files with 546 additions and 711 deletions
-
36app/src/main/java/awais/instagrabber/activities/MainActivity.kt
-
27app/src/main/java/awais/instagrabber/fragments/LikesViewerFragment.java
-
45app/src/main/java/awais/instagrabber/fragments/NotificationsViewerFragment.java
-
65app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java
-
53app/src/main/java/awais/instagrabber/fragments/imageedit/FiltersFragment.java
-
57app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java
-
47app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java
-
107app/src/main/java/awais/instagrabber/managers/ThreadManager.kt
-
55app/src/main/java/awais/instagrabber/repositories/MediaRepository.java
-
57app/src/main/java/awais/instagrabber/repositories/MediaRepository.kt
-
40app/src/main/java/awais/instagrabber/utils/MediaUploader.kt
-
182app/src/main/java/awais/instagrabber/viewmodels/PostViewV2ViewModel.kt
-
317app/src/main/java/awais/instagrabber/webservices/MediaService.java
-
169app/src/main/java/awais/instagrabber/webservices/MediaService.kt
@ -1,55 +0,0 @@ |
|||||
package awais.instagrabber.repositories; |
|
||||
|
|
||||
import java.util.Map; |
|
||||
|
|
||||
import awais.instagrabber.repositories.responses.LikersResponse; |
|
||||
import awais.instagrabber.repositories.responses.MediaInfoResponse; |
|
||||
import retrofit2.Call; |
|
||||
import retrofit2.http.FieldMap; |
|
||||
import retrofit2.http.FormUrlEncoded; |
|
||||
import retrofit2.http.GET; |
|
||||
import retrofit2.http.Header; |
|
||||
import retrofit2.http.POST; |
|
||||
import retrofit2.http.Path; |
|
||||
import retrofit2.http.Query; |
|
||||
import retrofit2.http.QueryMap; |
|
||||
|
|
||||
public interface MediaRepository { |
|
||||
@GET("/api/v1/media/{mediaId}/info/") |
|
||||
Call<MediaInfoResponse> fetch(@Path("mediaId") final long mediaId); |
|
||||
|
|
||||
@GET("/api/v1/media/{mediaId}/{action}/") |
|
||||
Call<LikersResponse> fetchLikes(@Path("mediaId") final String mediaId, |
|
||||
@Path("action") final String action); // one of "likers" or "comment_likers" |
|
||||
|
|
||||
@FormUrlEncoded |
|
||||
@POST("/api/v1/media/{mediaId}/{action}/") |
|
||||
Call<String> action(@Path("action") final String action, |
|
||||
@Path("mediaId") final String mediaId, |
|
||||
@FieldMap final Map<String, String> signedForm); |
|
||||
|
|
||||
@FormUrlEncoded |
|
||||
@POST("/api/v1/media/{mediaId}/edit_media/") |
|
||||
Call<String> editCaption(@Path("mediaId") final String mediaId, |
|
||||
@FieldMap final Map<String, String> signedForm); |
|
||||
|
|
||||
@GET("/api/v1/language/translate/") |
|
||||
Call<String> translate(@QueryMap final Map<String, String> form); |
|
||||
|
|
||||
@FormUrlEncoded |
|
||||
@POST("/api/v1/media/upload_finish/") |
|
||||
Call<String> uploadFinish(@Header("retry_context") final String retryContext, |
|
||||
@QueryMap Map<String, String> queryParams, |
|
||||
@FieldMap final Map<String, String> signedForm); |
|
||||
|
|
||||
@FormUrlEncoded |
|
||||
@POST("/api/v1/media/{mediaId}/delete/") |
|
||||
Call<String> delete(@Path("mediaId") final String mediaId, |
|
||||
@Query("media_type") final String mediaType, |
|
||||
@FieldMap final Map<String, String> signedForm); |
|
||||
|
|
||||
@FormUrlEncoded |
|
||||
@POST("/api/v1/media/{mediaId}/archive/") |
|
||||
Call<String> archive(@Path("mediaId") final String mediaId, |
|
||||
@FieldMap final Map<String, String> signedForm); |
|
||||
} |
|
@ -0,0 +1,57 @@ |
|||||
|
package awais.instagrabber.repositories |
||||
|
|
||||
|
import awais.instagrabber.repositories.responses.LikersResponse |
||||
|
import awais.instagrabber.repositories.responses.MediaInfoResponse |
||||
|
import retrofit2.http.* |
||||
|
|
||||
|
interface MediaRepository { |
||||
|
@GET("/api/v1/media/{mediaId}/info/") |
||||
|
suspend fun fetch(@Path("mediaId") mediaId: Long): MediaInfoResponse |
||||
|
|
||||
|
@GET("/api/v1/media/{mediaId}/{action}/") |
||||
|
suspend fun fetchLikes( |
||||
|
@Path("mediaId") mediaId: String, // one of "likers" or "comment_likers" |
||||
|
@Path("action") action: String, |
||||
|
): LikersResponse |
||||
|
|
||||
|
@FormUrlEncoded |
||||
|
@POST("/api/v1/media/{mediaId}/{action}/") |
||||
|
suspend fun action( |
||||
|
@Path("action") action: String, |
||||
|
@Path("mediaId") mediaId: String, |
||||
|
@FieldMap signedForm: Map<String, String>, |
||||
|
): String |
||||
|
|
||||
|
@FormUrlEncoded |
||||
|
@POST("/api/v1/media/{mediaId}/edit_media/") |
||||
|
suspend fun editCaption( |
||||
|
@Path("mediaId") mediaId: String, |
||||
|
@FieldMap signedForm: Map<String, String>, |
||||
|
): String |
||||
|
|
||||
|
@GET("/api/v1/language/translate/") |
||||
|
suspend fun translate(@QueryMap form: Map<String, String>): String |
||||
|
|
||||
|
@FormUrlEncoded |
||||
|
@POST("/api/v1/media/upload_finish/") |
||||
|
suspend fun uploadFinish( |
||||
|
@Header("retry_context") retryContext: String, |
||||
|
@QueryMap queryParams: Map<String, String>, |
||||
|
@FieldMap signedForm: Map<String, String>, |
||||
|
): String |
||||
|
|
||||
|
@FormUrlEncoded |
||||
|
@POST("/api/v1/media/{mediaId}/delete/") |
||||
|
suspend fun delete( |
||||
|
@Path("mediaId") mediaId: String, |
||||
|
@Query("media_type") mediaType: String, |
||||
|
@FieldMap signedForm: Map<String, String>, |
||||
|
): String |
||||
|
|
||||
|
@FormUrlEncoded |
||||
|
@POST("/api/v1/media/{mediaId}/archive/") |
||||
|
suspend fun archive( |
||||
|
@Path("mediaId") mediaId: String, |
||||
|
@FieldMap signedForm: Map<String, String>, |
||||
|
): String |
||||
|
} |
@ -1,317 +0,0 @@ |
|||||
package awais.instagrabber.webservices; |
|
||||
|
|
||||
import android.util.Log; |
|
||||
|
|
||||
import androidx.annotation.NonNull; |
|
||||
|
|
||||
import com.google.common.collect.ImmutableList; |
|
||||
import com.google.common.collect.ImmutableMap; |
|
||||
|
|
||||
import org.json.JSONException; |
|
||||
import org.json.JSONObject; |
|
||||
|
|
||||
import java.util.Collections; |
|
||||
import java.util.HashMap; |
|
||||
import java.util.List; |
|
||||
import java.util.Map; |
|
||||
import java.util.Objects; |
|
||||
|
|
||||
import awais.instagrabber.models.enums.MediaItemType; |
|
||||
import awais.instagrabber.repositories.MediaRepository; |
|
||||
import awais.instagrabber.repositories.requests.Clip; |
|
||||
import awais.instagrabber.repositories.requests.UploadFinishOptions; |
|
||||
import awais.instagrabber.repositories.requests.VideoOptions; |
|
||||
import awais.instagrabber.repositories.responses.LikersResponse; |
|
||||
import awais.instagrabber.repositories.responses.Media; |
|
||||
import awais.instagrabber.repositories.responses.MediaInfoResponse; |
|
||||
import awais.instagrabber.repositories.responses.User; |
|
||||
import awais.instagrabber.utils.DateUtils; |
|
||||
import awais.instagrabber.utils.MediaUploadHelper; |
|
||||
import awais.instagrabber.utils.TextUtils; |
|
||||
import awais.instagrabber.utils.Utils; |
|
||||
import retrofit2.Call; |
|
||||
import retrofit2.Callback; |
|
||||
import retrofit2.Response; |
|
||||
|
|
||||
public class MediaService extends BaseService { |
|
||||
private static final String TAG = "MediaService"; |
|
||||
private static final List<MediaItemType> DELETABLE_ITEMS_TYPES = ImmutableList.of(MediaItemType.MEDIA_TYPE_IMAGE, |
|
||||
MediaItemType.MEDIA_TYPE_VIDEO, |
|
||||
MediaItemType.MEDIA_TYPE_SLIDER); |
|
||||
|
|
||||
private final MediaRepository repository; |
|
||||
private final String deviceUuid, csrfToken; |
|
||||
private final long userId; |
|
||||
|
|
||||
private static MediaService instance; |
|
||||
|
|
||||
private MediaService(final String deviceUuid, |
|
||||
final String csrfToken, |
|
||||
final long userId) { |
|
||||
this.deviceUuid = deviceUuid; |
|
||||
this.csrfToken = csrfToken; |
|
||||
this.userId = userId; |
|
||||
repository = RetrofitFactory.INSTANCE |
|
||||
.getRetrofit() |
|
||||
.create(MediaRepository.class); |
|
||||
} |
|
||||
|
|
||||
public String getCsrfToken() { |
|
||||
return csrfToken; |
|
||||
} |
|
||||
|
|
||||
public String getDeviceUuid() { |
|
||||
return deviceUuid; |
|
||||
} |
|
||||
|
|
||||
public long getUserId() { |
|
||||
return userId; |
|
||||
} |
|
||||
|
|
||||
public static MediaService getInstance(final String deviceUuid, final String csrfToken, final long userId) { |
|
||||
if (instance == null |
|
||||
|| !Objects.equals(instance.getCsrfToken(), csrfToken) |
|
||||
|| !Objects.equals(instance.getDeviceUuid(), deviceUuid) |
|
||||
|| !Objects.equals(instance.getUserId(), userId)) { |
|
||||
instance = new MediaService(deviceUuid, csrfToken, userId); |
|
||||
} |
|
||||
return instance; |
|
||||
} |
|
||||
|
|
||||
public void fetch(final long mediaId, |
|
||||
final ServiceCallback<Media> callback) { |
|
||||
final Call<MediaInfoResponse> request = repository.fetch(mediaId); |
|
||||
request.enqueue(new Callback<MediaInfoResponse>() { |
|
||||
@Override |
|
||||
public void onResponse(@NonNull final Call<MediaInfoResponse> call, |
|
||||
@NonNull final Response<MediaInfoResponse> response) { |
|
||||
if (callback == null) return; |
|
||||
final MediaInfoResponse mediaInfoResponse = response.body(); |
|
||||
if (mediaInfoResponse == null || mediaInfoResponse.getItems() == null || mediaInfoResponse.getItems().isEmpty()) { |
|
||||
callback.onSuccess(null); |
|
||||
return; |
|
||||
} |
|
||||
callback.onSuccess(mediaInfoResponse.getItems().get(0)); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void onFailure(@NonNull final Call<MediaInfoResponse> call, |
|
||||
@NonNull final Throwable t) { |
|
||||
if (callback != null) { |
|
||||
callback.onFailure(t); |
|
||||
} |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
public void like(final String mediaId, |
|
||||
final ServiceCallback<Boolean> callback) { |
|
||||
action(mediaId, "like", null, callback); |
|
||||
} |
|
||||
|
|
||||
public void unlike(final String mediaId, |
|
||||
final ServiceCallback<Boolean> callback) { |
|
||||
action(mediaId, "unlike", null, callback); |
|
||||
} |
|
||||
|
|
||||
public void save(final String mediaId, |
|
||||
final String collection, |
|
||||
final ServiceCallback<Boolean> callback) { |
|
||||
action(mediaId, "save", collection, callback); |
|
||||
} |
|
||||
|
|
||||
public void unsave(final String mediaId, |
|
||||
final ServiceCallback<Boolean> callback) { |
|
||||
action(mediaId, "unsave", null, callback); |
|
||||
} |
|
||||
|
|
||||
private void action(final String mediaId, |
|
||||
final String action, |
|
||||
final String collection, |
|
||||
final ServiceCallback<Boolean> callback) { |
|
||||
final Map<String, Object> form = new HashMap<>(); |
|
||||
form.put("media_id", mediaId); |
|
||||
form.put("_csrftoken", csrfToken); |
|
||||
form.put("_uid", userId); |
|
||||
form.put("_uuid", deviceUuid); |
|
||||
// form.put("radio_type", "wifi-none"); |
|
||||
if (action.equals("save") && !TextUtils.isEmpty(collection)) form.put("added_collection_ids", "[" + collection + "]"); |
|
||||
// there also exists "removed_collection_ids" which can be used with "save" and "unsave" |
|
||||
final Map<String, String> signedForm = Utils.sign(form); |
|
||||
final Call<String> request = repository.action(action, mediaId, 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 body = response.body(); |
|
||||
if (body == null) { |
|
||||
callback.onFailure(new RuntimeException("Returned body is null")); |
|
||||
return; |
|
||||
} |
|
||||
try { |
|
||||
final JSONObject jsonObject = new JSONObject(body); |
|
||||
final String status = jsonObject.optString("status"); |
|
||||
callback.onSuccess(status.equals("ok")); |
|
||||
} catch (JSONException 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 editCaption(final String postId, |
|
||||
final String newCaption, |
|
||||
@NonNull final ServiceCallback<Boolean> callback) { |
|
||||
final Map<String, Object> form = new HashMap<>(); |
|
||||
form.put("_csrftoken", csrfToken); |
|
||||
form.put("_uid", userId); |
|
||||
form.put("_uuid", deviceUuid); |
|
||||
form.put("igtv_feed_preview", "false"); |
|
||||
form.put("media_id", postId); |
|
||||
form.put("caption_text", newCaption); |
|
||||
final Map<String, String> signedForm = Utils.sign(form); |
|
||||
final Call<String> request = repository.editCaption(postId, signedForm); |
|
||||
request.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, "Error occurred while editing caption"); |
|
||||
callback.onSuccess(false); |
|
||||
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, "Error parsing body", e); |
|
||||
callback.onFailure(e); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) { |
|
||||
Log.e(TAG, "Error editing caption", t); |
|
||||
callback.onFailure(t); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
public void fetchLikes(final String mediaId, |
|
||||
final boolean isComment, |
|
||||
@NonNull final ServiceCallback<List<User>> callback) { |
|
||||
final Call<LikersResponse> likesRequest = repository.fetchLikes(mediaId, isComment ? "comment_likers" : "likers"); |
|
||||
likesRequest.enqueue(new Callback<LikersResponse>() { |
|
||||
@Override |
|
||||
public void onResponse(@NonNull final Call<LikersResponse> call, @NonNull final Response<LikersResponse> response) { |
|
||||
final LikersResponse likersResponse = response.body(); |
|
||||
if (likersResponse == null) { |
|
||||
Log.e(TAG, "Error occurred while fetching likes of " + mediaId); |
|
||||
callback.onSuccess(null); |
|
||||
return; |
|
||||
} |
|
||||
callback.onSuccess(likersResponse.getUsers()); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void onFailure(@NonNull final Call<LikersResponse> call, @NonNull final Throwable t) { |
|
||||
Log.e(TAG, "Error getting likes", t); |
|
||||
callback.onFailure(t); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
public void translate(final String id, |
|
||||
final String type, // 1 caption 2 comment 3 bio |
|
||||
@NonNull final ServiceCallback<String> callback) { |
|
||||
final Map<String, String> form = new HashMap<>(); |
|
||||
form.put("id", String.valueOf(id)); |
|
||||
form.put("type", type); |
|
||||
final Call<String> request = repository.translate(form); |
|
||||
request.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, "Error occurred while translating"); |
|
||||
callback.onSuccess(null); |
|
||||
return; |
|
||||
} |
|
||||
try { |
|
||||
final JSONObject jsonObject = new JSONObject(body); |
|
||||
final String translation = jsonObject.optString("translation"); |
|
||||
callback.onSuccess(translation); |
|
||||
} catch (JSONException e) { |
|
||||
// Log.e(TAG, "Error parsing body", e); |
|
||||
callback.onFailure(e); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public void onFailure(@NonNull final Call<String> call, @NonNull final Throwable t) { |
|
||||
Log.e(TAG, "Error translating", t); |
|
||||
callback.onFailure(t); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
public Call<String> uploadFinish(@NonNull final UploadFinishOptions options) { |
|
||||
if (options.getVideoOptions() != null) { |
|
||||
final VideoOptions videoOptions = options.getVideoOptions(); |
|
||||
if (videoOptions.getClips().isEmpty()) { |
|
||||
videoOptions.setClips(Collections.singletonList(new Clip(videoOptions.getLength(), options.getSourceType()))); |
|
||||
} |
|
||||
} |
|
||||
final String timezoneOffset = String.valueOf(DateUtils.getTimezoneOffset()); |
|
||||
final ImmutableMap.Builder<String, Object> formBuilder = ImmutableMap.<String, Object>builder() |
|
||||
.put("timezone_offset", timezoneOffset) |
|
||||
.put("_csrftoken", csrfToken) |
|
||||
.put("source_type", options.getSourceType()) |
|
||||
.put("_uid", String.valueOf(userId)) |
|
||||
.put("_uuid", deviceUuid) |
|
||||
.put("upload_id", options.getUploadId()); |
|
||||
if (options.getVideoOptions() != null) { |
|
||||
formBuilder.putAll(options.getVideoOptions().getMap()); |
|
||||
} |
|
||||
final Map<String, String> queryMap = options.getVideoOptions() != null ? ImmutableMap.of("video", "1") : Collections.emptyMap(); |
|
||||
final Map<String, String> signedForm = Utils.sign(formBuilder.build()); |
|
||||
return repository.uploadFinish(MediaUploadHelper.getRetryContextString(), queryMap, signedForm); |
|
||||
} |
|
||||
|
|
||||
public Call<String> delete(@NonNull final String postId, |
|
||||
@NonNull final MediaItemType type) { |
|
||||
if (!DELETABLE_ITEMS_TYPES.contains(type)) return null; |
|
||||
final Map<String, Object> form = new HashMap<>(); |
|
||||
form.put("_csrftoken", csrfToken); |
|
||||
form.put("_uid", userId); |
|
||||
form.put("_uuid", deviceUuid); |
|
||||
form.put("igtv_feed_preview", "false"); |
|
||||
form.put("media_id", postId); |
|
||||
final Map<String, String> signedForm = Utils.sign(form); |
|
||||
final String mediaType; |
|
||||
switch (type) { |
|
||||
case MEDIA_TYPE_IMAGE: |
|
||||
mediaType = "PHOTO"; |
|
||||
break; |
|
||||
case MEDIA_TYPE_VIDEO: |
|
||||
mediaType = "VIDEO"; |
|
||||
break; |
|
||||
case MEDIA_TYPE_SLIDER: |
|
||||
mediaType = "CAROUSEL"; |
|
||||
break; |
|
||||
default: |
|
||||
return null; |
|
||||
} |
|
||||
return repository.delete(postId, mediaType, signedForm); |
|
||||
} |
|
||||
} |
|
@ -0,0 +1,169 @@ |
|||||
|
package awais.instagrabber.webservices |
||||
|
|
||||
|
import awais.instagrabber.models.enums.MediaItemType |
||||
|
import awais.instagrabber.repositories.MediaRepository |
||||
|
import awais.instagrabber.repositories.requests.Clip |
||||
|
import awais.instagrabber.repositories.requests.UploadFinishOptions |
||||
|
import awais.instagrabber.repositories.responses.Media |
||||
|
import awais.instagrabber.repositories.responses.User |
||||
|
import awais.instagrabber.utils.DateUtils |
||||
|
import awais.instagrabber.utils.Utils |
||||
|
import awais.instagrabber.utils.retryContextString |
||||
|
import awais.instagrabber.webservices.RetrofitFactory.retrofit |
||||
|
import org.json.JSONObject |
||||
|
|
||||
|
class MediaService private constructor( |
||||
|
val deviceUuid: String, |
||||
|
val csrfToken: String, |
||||
|
val userId: Long, |
||||
|
) : BaseService() { |
||||
|
private val repository: MediaRepository = retrofit.create(MediaRepository::class.java) |
||||
|
|
||||
|
suspend fun fetch( |
||||
|
mediaId: Long, |
||||
|
): Media? { |
||||
|
val response = repository.fetch(mediaId) |
||||
|
return if (response.items.isNullOrEmpty()) { |
||||
|
null |
||||
|
} else response.items[0] |
||||
|
} |
||||
|
|
||||
|
suspend fun like(mediaId: String): Boolean = action(mediaId, "like", null) |
||||
|
|
||||
|
suspend fun unlike(mediaId: String): Boolean = action(mediaId, "unlike", null) |
||||
|
|
||||
|
suspend fun save(mediaId: String, collection: String?): Boolean = action(mediaId, "save", collection) |
||||
|
|
||||
|
suspend fun unsave(mediaId: String): Boolean = action(mediaId, "unsave", null) |
||||
|
|
||||
|
private suspend fun action( |
||||
|
mediaId: String, |
||||
|
action: String, |
||||
|
collection: String?, |
||||
|
): Boolean { |
||||
|
val form: MutableMap<String, Any> = mutableMapOf( |
||||
|
"media_id" to mediaId, |
||||
|
"_csrftoken" to csrfToken, |
||||
|
"_uid" to userId, |
||||
|
"_uuid" to deviceUuid, |
||||
|
) |
||||
|
// form.put("radio_type", "wifi-none"); |
||||
|
if (action == "save" && !collection.isNullOrBlank()) { |
||||
|
form["added_collection_ids"] = "[$collection]" |
||||
|
} |
||||
|
// there also exists "removed_collection_ids" which can be used with "save" and "unsave" |
||||
|
val signedForm = Utils.sign(form) |
||||
|
val response = repository.action(action, mediaId, signedForm) |
||||
|
val jsonObject = JSONObject(response) |
||||
|
val status = jsonObject.optString("status") |
||||
|
return status == "ok" |
||||
|
} |
||||
|
|
||||
|
suspend fun editCaption( |
||||
|
postId: String, |
||||
|
newCaption: String, |
||||
|
): Boolean { |
||||
|
val form = mapOf( |
||||
|
"_csrftoken" to csrfToken, |
||||
|
"_uid" to userId, |
||||
|
"_uuid" to deviceUuid, |
||||
|
"igtv_feed_preview" to "false", |
||||
|
"media_id" to postId, |
||||
|
"caption_text" to newCaption, |
||||
|
) |
||||
|
val signedForm = Utils.sign(form) |
||||
|
val response = repository.editCaption(postId, signedForm) |
||||
|
val jsonObject = JSONObject(response) |
||||
|
val status = jsonObject.optString("status") |
||||
|
return status == "ok" |
||||
|
} |
||||
|
|
||||
|
suspend fun fetchLikes( |
||||
|
mediaId: String, |
||||
|
isComment: Boolean, |
||||
|
): List<User> { |
||||
|
val response = repository.fetchLikes(mediaId, if (isComment) "comment_likers" else "likers") |
||||
|
return response.users |
||||
|
} |
||||
|
|
||||
|
suspend fun translate( |
||||
|
id: String, |
||||
|
type: String, // 1 caption 2 comment 3 bio |
||||
|
): String { |
||||
|
val form = mapOf( |
||||
|
"id" to id, |
||||
|
"type" to type, |
||||
|
) |
||||
|
val response = repository.translate(form) |
||||
|
val jsonObject = JSONObject(response) |
||||
|
return jsonObject.optString("translation") |
||||
|
} |
||||
|
|
||||
|
suspend fun uploadFinish(options: UploadFinishOptions): String { |
||||
|
if (options.videoOptions != null) { |
||||
|
val videoOptions = options.videoOptions |
||||
|
if (videoOptions.clips.isEmpty()) { |
||||
|
videoOptions.clips = listOf(Clip(videoOptions.length, options.sourceType)) |
||||
|
} |
||||
|
} |
||||
|
val timezoneOffset = DateUtils.getTimezoneOffset().toString() |
||||
|
val form = mutableMapOf<String, Any>( |
||||
|
"timezone_offset" to timezoneOffset, |
||||
|
"_csrftoken" to csrfToken, |
||||
|
"source_type" to options.sourceType, |
||||
|
"_uid" to userId.toString(), |
||||
|
"_uuid" to deviceUuid, |
||||
|
"upload_id" to options.uploadId, |
||||
|
) |
||||
|
if (options.videoOptions != null) { |
||||
|
form.putAll(options.videoOptions.map) |
||||
|
} |
||||
|
val queryMap = if (options.videoOptions != null) mapOf("video" to "1") else emptyMap() |
||||
|
val signedForm = Utils.sign(form) |
||||
|
return repository.uploadFinish(retryContextString, queryMap, signedForm) |
||||
|
} |
||||
|
|
||||
|
suspend fun delete( |
||||
|
postId: String, |
||||
|
type: MediaItemType, |
||||
|
): String? { |
||||
|
if (!DELETABLE_ITEMS_TYPES.contains(type)) return null |
||||
|
val form = mapOf( |
||||
|
"_csrftoken" to csrfToken, |
||||
|
"_uid" to userId, |
||||
|
"_uuid" to deviceUuid, |
||||
|
"igtv_feed_preview" to "false", |
||||
|
"media_id" to postId, |
||||
|
) |
||||
|
val signedForm = Utils.sign(form) |
||||
|
val mediaType: String = when (type) { |
||||
|
MediaItemType.MEDIA_TYPE_IMAGE -> "PHOTO" |
||||
|
MediaItemType.MEDIA_TYPE_VIDEO -> "VIDEO" |
||||
|
MediaItemType.MEDIA_TYPE_SLIDER -> "CAROUSEL" |
||||
|
else -> return null |
||||
|
} |
||||
|
return repository.delete(postId, mediaType, signedForm) |
||||
|
} |
||||
|
|
||||
|
companion object { |
||||
|
private val DELETABLE_ITEMS_TYPES = listOf( |
||||
|
MediaItemType.MEDIA_TYPE_IMAGE, |
||||
|
MediaItemType.MEDIA_TYPE_VIDEO, |
||||
|
MediaItemType.MEDIA_TYPE_SLIDER |
||||
|
) |
||||
|
private lateinit var instance: MediaService |
||||
|
|
||||
|
@JvmStatic |
||||
|
fun getInstance(deviceUuid: String, csrfToken: String, userId: Long): MediaService { |
||||
|
if (!this::instance.isInitialized |
||||
|
|| instance.csrfToken != csrfToken |
||||
|
|| instance.deviceUuid != deviceUuid |
||||
|
|| instance.userId != userId |
||||
|
) { |
||||
|
instance = MediaService(deviceUuid, csrfToken, userId) |
||||
|
} |
||||
|
return instance |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue