diff --git a/app/src/main/java/awais/instagrabber/InstaGrabberApplication.java b/app/src/main/java/awais/instagrabber/InstaGrabberApplication.java index 422a1d2d..f28e529b 100644 --- a/app/src/main/java/awais/instagrabber/InstaGrabberApplication.java +++ b/app/src/main/java/awais/instagrabber/InstaGrabberApplication.java @@ -21,7 +21,7 @@ import awais.instagrabber.utils.SettingsHelper; import awaisomereport.CrashReporter; import awaisomereport.LogCollector; -import static awais.instagrabber.utils.Utils.NET_COOKIE_MANAGER; +import static awais.instagrabber.utils.CookieUtils.NET_COOKIE_MANAGER; import static awais.instagrabber.utils.Utils.clipboardManager; import static awais.instagrabber.utils.Utils.dataBox; import static awais.instagrabber.utils.Utils.datetimeParser; diff --git a/app/src/main/java/awais/instagrabber/activities/Login.java b/app/src/main/java/awais/instagrabber/activities/Login.java index 0e4c7fc5..a7f06b67 100755 --- a/app/src/main/java/awais/instagrabber/activities/Login.java +++ b/app/src/main/java/awais/instagrabber/activities/Login.java @@ -20,7 +20,8 @@ import androidx.annotation.Nullable; import awais.instagrabber.R; import awais.instagrabber.databinding.ActivityLoginBinding; import awais.instagrabber.utils.Constants; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.CookieUtils; +import awais.instagrabber.utils.TextUtils; public final class Login extends BaseLanguageActivity implements View.OnClickListener, CompoundButton.OnCheckedChangeListener { private final WebViewClient webViewClient = new WebViewClient() { @@ -32,8 +33,8 @@ public final class Login extends BaseLanguageActivity implements View.OnClickLis @Override public void onPageFinished(final WebView view, final String url) { webViewUrl = url; - final String mainCookie = Utils.getCookie(url); - if (Utils.isEmpty(mainCookie) || !mainCookie.contains("; ds_user_id=")) { + final String mainCookie = CookieUtils.getCookie(url); + if (TextUtils.isEmpty(mainCookie) || !mainCookie.contains("; ds_user_id=")) { ready = true; return; } @@ -75,8 +76,8 @@ public final class Login extends BaseLanguageActivity implements View.OnClickLis return; } if (v == loginBinding.cookies) { - final String mainCookie = Utils.getCookie(webViewUrl); - if (Utils.isEmpty(mainCookie) || !mainCookie.contains("; ds_user_id=")) { + final String mainCookie = CookieUtils.getCookie(webViewUrl); + if (TextUtils.isEmpty(mainCookie) || !mainCookie.contains("; ds_user_id=")) { Toast.makeText(this, R.string.login_error_loading_cookies, Toast.LENGTH_SHORT).show(); return; } diff --git a/app/src/main/java/awais/instagrabber/activities/MainActivity.java b/app/src/main/java/awais/instagrabber/activities/MainActivity.java index 03b05587..98927c17 100644 --- a/app/src/main/java/awais/instagrabber/activities/MainActivity.java +++ b/app/src/main/java/awais/instagrabber/activities/MainActivity.java @@ -48,9 +48,10 @@ import awais.instagrabber.models.IntentModel; import awais.instagrabber.models.SuggestionModel; import awais.instagrabber.models.enums.SuggestionType; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.FlavorTown; import awais.instagrabber.utils.IntentUtils; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.TextUtils; import static awais.instagrabber.utils.NavigationExtensions.setupWithNavController; import static awais.instagrabber.utils.Utils.settingsHelper; @@ -105,7 +106,7 @@ public class MainActivity extends BaseLanguageActivity { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); final String cookie = settingsHelper.getString(Constants.COOKIE); - Utils.setupCookies(cookie); + CookieUtils.setupCookies(cookie); setContentView(binding.getRoot()); final Toolbar toolbar = binding.toolbar; setSupportActionBar(toolbar); @@ -268,7 +269,7 @@ public class MainActivity extends BaseLanguageActivity { private final Runnable runnable = () -> { cancelSuggestionsAsync(); - if (Utils.isEmpty(currentSearchQuery)) { + if (TextUtils.isEmpty(currentSearchQuery)) { suggestionAdapter.changeCursor(null); return; } @@ -315,7 +316,7 @@ public class MainActivity extends BaseLanguageActivity { private void setupBottomNavigationBar(final boolean setDefaultFromSettings) { int main_nav_ids = R.array.main_nav_ids; final String cookie = settingsHelper.getString(Constants.COOKIE); - isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null; + isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) != null; if (!isLoggedIn) { main_nav_ids = R.array.logged_out_main_nav_ids; binding.bottomNavView.getMenu().clear(); @@ -333,7 +334,7 @@ public class MainActivity extends BaseLanguageActivity { if (setDefaultFromSettings || !isLoggedIn) { final String defaultTabIdString = settingsHelper.getString(Constants.DEFAULT_TAB); try { - final int defaultNavId = Utils.isEmpty(defaultTabIdString) || !isLoggedIn + final int defaultNavId = TextUtils.isEmpty(defaultTabIdString) || !isLoggedIn ? R.navigation.profile_nav_graph : Integer.parseInt(defaultTabIdString); final int index = mainNavList.indexOf(defaultNavId); diff --git a/app/src/main/java/awais/instagrabber/activities/NotificationsViewer.java b/app/src/main/java/awais/instagrabber/activities/NotificationsViewer.java index d227154f..2f754167 100755 --- a/app/src/main/java/awais/instagrabber/activities/NotificationsViewer.java +++ b/app/src/main/java/awais/instagrabber/activities/NotificationsViewer.java @@ -1,7 +1,6 @@ package awais.instagrabber.activities; import android.content.DialogInterface; -import android.content.Intent; import android.content.res.Resources; import android.os.AsyncTask; import android.os.Bundle; @@ -28,9 +27,9 @@ import awais.instagrabber.databinding.ActivityNotificationBinding; import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.interfaces.MentionClickListener; import awais.instagrabber.models.NotificationModel; -import awais.instagrabber.models.PostModel; import awais.instagrabber.models.enums.NotificationType; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import static awais.instagrabber.utils.Utils.notificationManager; @@ -47,7 +46,7 @@ public final class NotificationsViewer extends BaseLanguageActivity implements S @Override protected void onCreate(@Nullable final Bundle savedInstanceState) { notificationManager.cancel(1800000000); - if (Utils.isEmpty(cookie)) { + if (TextUtils.isEmpty(cookie)) { Toast.makeText(this, R.string.activity_notloggedin, Toast.LENGTH_SHORT).show(); } super.onCreate(savedInstanceState); diff --git a/app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java b/app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java index 66d5af6f..6a00ff33 100755 --- a/app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java +++ b/app/src/main/java/awais/instagrabber/adapters/CommentsAdapter.java @@ -18,7 +18,7 @@ import awais.instagrabber.interfaces.MentionClickListener; import awais.instagrabber.models.CommentModel; import awais.instagrabber.models.ProfileModel; import awais.instagrabber.utils.LocaleUtils; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.TextUtils; public final class CommentsAdapter extends RecyclerView.Adapter implements Filterable { @@ -38,7 +38,7 @@ public final class CommentsAdapter extends RecyclerView.Adapter 0 && !Utils.isEmpty(filter)) { + if (commentModels != null && commentsLen > 0 && !TextUtils.isEmpty(filter)) { final String query = filter.toString().toLowerCase(); final ArrayList filterList = new ArrayList<>(commentsLen); diff --git a/app/src/main/java/awais/instagrabber/adapters/FollowAdapter.java b/app/src/main/java/awais/instagrabber/adapters/FollowAdapter.java index 7466022b..b951e9aa 100755 --- a/app/src/main/java/awais/instagrabber/adapters/FollowAdapter.java +++ b/app/src/main/java/awais/instagrabber/adapters/FollowAdapter.java @@ -20,7 +20,7 @@ import awais.instagrabber.R; import awais.instagrabber.adapters.viewholder.FollowsViewHolder; import awais.instagrabber.interfaces.OnGroupClickListener; import awais.instagrabber.models.FollowModel; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.TextUtils; import thoughtbot.expandableadapter.ExpandableGroup; import thoughtbot.expandableadapter.ExpandableList; import thoughtbot.expandableadapter.ExpandableListPosition; @@ -34,7 +34,7 @@ public final class FollowAdapter extends RecyclerView.Adapter mentionClickListener .onClick(binding.topPanel.location, location, false, true)); } diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageItemViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageItemViewHolder.java index 4564144f..75ef7689 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageItemViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageItemViewHolder.java @@ -18,13 +18,16 @@ import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.models.ProfileModel; import awais.instagrabber.models.direct_messages.DirectItemModel; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; public abstract class DirectMessageItemViewHolder extends RecyclerView.ViewHolder { private static final int MESSAGE_INCOMING = 69; private static final int MESSAGE_OUTGOING = 420; - private final ProfileModel myProfileHolder = ProfileModel.getDefaultProfileModel(Utils.getUserIdFromCookie(Utils.settingsHelper.getString(Constants.COOKIE))); + private final ProfileModel myProfileHolder = ProfileModel.getDefaultProfileModel( + CookieUtils.getUserIdFromCookie(Utils.settingsHelper.getString(Constants.COOKIE))); private final LayoutDmBaseBinding binding; private final String strDmYou; private final int itemMargin; @@ -56,7 +59,7 @@ public abstract class DirectMessageItemViewHolder extends RecyclerView.ViewHolde if (user != null && user != myProfileHolder) { text = user.getUsername(); } else if (user == myProfileHolder) text = ""; - text = (Utils.isEmpty(text) ? "" : text + " - ") + directItemModel.getDateTime(); + text = (TextUtils.isEmpty(text) ? "" : text + " - ") + directItemModel.getDateTime(); binding.tvUsername.setText(text); binding.tvUsername.setGravity(type == MESSAGE_INCOMING ? Gravity.START : Gravity.END); binding.ivProfilePic.setVisibility(type == MESSAGE_INCOMING ? View.VISIBLE : View.GONE); diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageLinkViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageLinkViewHolder.java index 2c277d75..d48a1cc3 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageLinkViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageLinkViewHolder.java @@ -7,7 +7,7 @@ import androidx.annotation.NonNull; import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.databinding.LayoutDmLinkBinding; import awais.instagrabber.models.direct_messages.DirectItemModel; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.TextUtils; public class DirectMessageLinkViewHolder extends DirectMessageItemViewHolder { @@ -26,21 +26,21 @@ public class DirectMessageLinkViewHolder extends DirectMessageItemViewHolder { final DirectItemModel.DirectItemLinkModel link = directItemModel.getLinkModel(); final DirectItemModel.DirectItemLinkContext linkContext = link.getLinkContext(); final String linkImageUrl = linkContext.getLinkImageUrl(); - if (Utils.isEmpty(linkImageUrl)) { + if (TextUtils.isEmpty(linkImageUrl)) { binding.ivLinkPreview.setVisibility(View.GONE); } else { getGlideRequestManager().load(linkImageUrl).into(binding.ivLinkPreview); } - if (Utils.isEmpty(linkContext.getLinkTitle())) { + if (TextUtils.isEmpty(linkContext.getLinkTitle())) { binding.tvLinkTitle.setVisibility(View.GONE); } else { binding.tvLinkTitle.setText(linkContext.getLinkTitle()); } - if (Utils.isEmpty(linkContext.getLinkSummary())) { + if (TextUtils.isEmpty(linkContext.getLinkSummary())) { binding.tvLinkSummary.setVisibility(View.GONE); } else { binding.tvLinkSummary.setText(linkContext.getLinkSummary()); } - binding.tvMessage.setText(Utils.getSpannableUrl(link.getText())); + binding.tvMessage.setText(TextUtils.getSpannableUrl(link.getText())); } } diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageRavenMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageRavenMediaViewHolder.java index 473778ac..5a7d59d7 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageRavenMediaViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageRavenMediaViewHolder.java @@ -12,7 +12,7 @@ import awais.instagrabber.models.direct_messages.DirectItemModel; import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.models.enums.RavenExpiringMediaType; import awais.instagrabber.models.enums.RavenMediaViewType; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.TextUtils; public class DirectMessageRavenMediaViewHolder extends DirectMessageItemViewHolder { @@ -33,7 +33,7 @@ public class DirectMessageRavenMediaViewHolder extends DirectMessageItemViewHold final DirectItemModel.DirectItemRavenMediaModel ravenMediaModel = directItemModel.getRavenMediaModel(); DirectItemModel.DirectItemMediaModel mediaModel = directItemModel.getMediaModel(); final boolean isExpired = ravenMediaModel == null || (mediaModel = ravenMediaModel.getMedia()) == null || - Utils.isEmpty(mediaModel.getThumbUrl()) && mediaModel.getPk() < 1; + TextUtils.isEmpty(mediaModel.getThumbUrl()) && mediaModel.getPk() < 1; DirectItemModel.RavenExpiringMediaActionSummaryModel mediaActionSummary = null; if (ravenMediaModel != null) { diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageReelShareViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageReelShareViewHolder.java index 31b50ea4..25993e1f 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageReelShareViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageReelShareViewHolder.java @@ -9,7 +9,7 @@ import awais.instagrabber.databinding.LayoutDmRavenMediaBinding; import awais.instagrabber.interfaces.MentionClickListener; import awais.instagrabber.models.direct_messages.DirectItemModel; import awais.instagrabber.models.enums.MediaItemType; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.TextUtils; public class DirectMessageReelShareViewHolder extends DirectMessageItemViewHolder { @@ -29,10 +29,10 @@ public class DirectMessageReelShareViewHolder extends DirectMessageItemViewHolde public void bindItem(final DirectItemModel directItemModel) { final DirectItemModel.DirectItemReelShareModel reelShare = directItemModel.getReelShare(); CharSequence text = reelShare.getText(); - if (Utils.isEmpty(text)) { + if (TextUtils.isEmpty(text)) { binding.tvMessage.setVisibility(View.GONE); } else { - if (Utils.hasMentions(text)) text = Utils.getMentionText(text); // for mentions + if (TextUtils.hasMentions(text)) text = TextUtils.getMentionText(text); // for mentions binding.tvMessage.setText(text); } final DirectItemModel.DirectItemMediaModel reelShareMedia = reelShare.getMedia(); diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageStoryShareViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageStoryShareViewHolder.java index 155cd86f..28ca4332 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageStoryShareViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageStoryShareViewHolder.java @@ -9,7 +9,7 @@ import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.databinding.LayoutDmStoryShareBinding; import awais.instagrabber.models.direct_messages.DirectItemModel; import awais.instagrabber.models.enums.MediaItemType; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.TextUtils; import static androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT; @@ -34,7 +34,7 @@ public class DirectMessageStoryShareViewHolder extends DirectMessageItemViewHold binding.tvMessage.setVisibility(View.VISIBLE); } else { final String text = reelShare.getText(); - if (!Utils.isEmpty(text)) { + if (!TextUtils.isEmpty(text)) { binding.tvMessage.setText(text); binding.tvMessage.setVisibility(View.VISIBLE); } diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageTextViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageTextViewHolder.java index 12fe1b38..e8d0bb72 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageTextViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageTextViewHolder.java @@ -12,7 +12,7 @@ import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.databinding.LayoutDmTextBinding; import awais.instagrabber.interfaces.MentionClickListener; import awais.instagrabber.models.direct_messages.DirectItemModel; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.TextUtils; public class DirectMessageTextViewHolder extends DirectMessageItemViewHolder { @@ -32,8 +32,8 @@ public class DirectMessageTextViewHolder extends DirectMessageItemViewHolder { public void bindItem(final DirectItemModel directItemModel) { final Context context = itemView.getContext(); CharSequence text = directItemModel.getText(); - text = Utils.getSpannableUrl(text.toString()); // for urls - if (Utils.hasMentions(text)) text = Utils.getMentionText(text); // for mentions + text = TextUtils.getSpannableUrl(text.toString()); // for urls + if (TextUtils.hasMentions(text)) text = TextUtils.getMentionText(text); // for mentions if (text instanceof Spanned) binding.tvMessage.setText(text, TextView.BufferType.SPANNABLE); else if (text == "") { diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageVoiceMediaViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageVoiceMediaViewHolder.java index f6790e54..bbee55fa 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageVoiceMediaViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/directmessages/DirectMessageVoiceMediaViewHolder.java @@ -9,7 +9,7 @@ import androidx.annotation.NonNull; import awais.instagrabber.databinding.LayoutDmBaseBinding; import awais.instagrabber.databinding.LayoutDmVoiceMediaBinding; import awais.instagrabber.models.direct_messages.DirectItemModel; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.NumberUtils; public class DirectMessageVoiceMediaViewHolder extends DirectMessageItemViewHolder { @@ -61,13 +61,13 @@ public class DirectMessageVoiceMediaViewHolder extends DirectMessageItemViewHold if (waveformData != null) binding.waveformSeekBar.setSample(waveformData); final long durationMs = voiceMediaModel.getDurationMs(); - binding.tvVoiceDuration.setText(Utils.millisToString(durationMs)); + binding.tvVoiceDuration.setText(NumberUtils.millisToString(durationMs)); binding.waveformSeekBar.setProgress(voiceMediaModel.getProgress()); binding.waveformSeekBar.setProgressChangeListener((waveformSeekBar, progress, fromUser) -> { // todo progress audio player voiceMediaModel.setProgress(progress); if (fromUser) - binding.tvVoiceDuration.setText(Utils.millisToString(durationMs * progress / 100)); + binding.tvVoiceDuration.setText(NumberUtils.millisToString(durationMs * progress / 100)); }); binding.btnPlayVoice.setTag(voiceMediaModel); } else { diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedItemViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedItemViewHolder.java index ccdabee6..ce28419f 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedItemViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedItemViewHolder.java @@ -16,7 +16,7 @@ import awais.instagrabber.databinding.ItemFeedTopBinding; import awais.instagrabber.interfaces.MentionClickListener; import awais.instagrabber.models.FeedModel; import awais.instagrabber.models.ProfileModel; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.TextUtils; public abstract class FeedItemViewHolder extends RecyclerView.ViewHolder { public static final int MAX_CHARS = 255; @@ -71,11 +71,11 @@ public abstract class FeedItemViewHolder extends RecyclerView.ViewHolder { final String locationId = feedModel.getLocationId(); setLocation(locationName, locationId); CharSequence postCaption = feedModel.getPostCaption(); - final boolean captionEmpty = Utils.isEmpty(postCaption); + final boolean captionEmpty = TextUtils.isEmpty(postCaption); bottomBinding.viewerCaption.setVisibility(captionEmpty ? View.GONE : View.VISIBLE); if (!captionEmpty) { - if (Utils.hasMentions(postCaption)) { - postCaption = Utils.getMentionText(postCaption); + if (TextUtils.hasMentions(postCaption)) { + postCaption = TextUtils.getMentionText(postCaption); feedModel.setPostCaption(postCaption); bottomBinding.viewerCaption.setText(postCaption, TextView.BufferType.SPANNABLE); } else { @@ -87,7 +87,7 @@ public abstract class FeedItemViewHolder extends RecyclerView.ViewHolder { } private void setLocation(final String locationName, final String locationId) { - if (Utils.isEmpty(locationName)) { + if (TextUtils.isEmpty(locationName)) { topBinding.location.setVisibility(View.GONE); topBinding.title.setLayoutParams(new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT @@ -110,7 +110,7 @@ public abstract class FeedItemViewHolder extends RecyclerView.ViewHolder { * @return isExpanded */ public static boolean expandCollapseTextView(@NonNull final RamboTextView textView, final CharSequence caption) { - if (Utils.isEmpty(caption)) return false; + if (TextUtils.isEmpty(caption)) return false; final TextView.BufferType bufferType = caption instanceof Spanned ? TextView.BufferType.SPANNABLE : TextView.BufferType.NORMAL; @@ -119,16 +119,16 @@ public abstract class FeedItemViewHolder extends RecyclerView.ViewHolder { textView.setCaptionIsExpanded(false); return true; } - int i = Utils.indexOfChar(caption, '\r', 0); - if (i == -1) i = Utils.indexOfChar(caption, '\n', 0); + int i = TextUtils.indexOfChar(caption, '\r', 0); + if (i == -1) i = TextUtils.indexOfChar(caption, '\n', 0); if (i == -1) i = MAX_CHARS; final int captionLen = caption.length(); final int minTrim = Math.min(MAX_CHARS, i); if (captionLen <= minTrim) return false; - if (Utils.hasMentions(caption)) - textView.setText(Utils.getMentionText(caption), TextView.BufferType.SPANNABLE); + if (TextUtils.hasMentions(caption)) + textView.setText(TextUtils.getMentionText(caption), TextView.BufferType.SPANNABLE); textView.setCaptionIsExpandable(true); textView.setCaptionIsExpanded(true); return true; diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedPhotoViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedPhotoViewHolder.java index 2e8c33bb..f89a2624 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedPhotoViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedPhotoViewHolder.java @@ -16,6 +16,7 @@ import com.facebook.imagepipeline.request.ImageRequestBuilder; import awais.instagrabber.databinding.ItemFeedPhotoBinding; import awais.instagrabber.interfaces.MentionClickListener; import awais.instagrabber.models.FeedModel; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; public class FeedPhotoViewHolder extends FeedItemViewHolder { @@ -50,7 +51,7 @@ public class FeedPhotoViewHolder extends FeedItemViewHolder { binding.imageViewer.requestLayout(); final String thumbnailUrl = feedModel.getThumbnailUrl(); String url = feedModel.getDisplayUrl(); - if (Utils.isEmpty(url)) url = thumbnailUrl; + if (TextUtils.isEmpty(url)) url = thumbnailUrl; final ImageRequest requestBuilder = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url)) .setLocalThumbnailPreviewsEnabled(true) .setProgressiveRenderingEnabled(true) diff --git a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedVideoViewHolder.java b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedVideoViewHolder.java index 39ee0e15..2887cbd4 100644 --- a/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedVideoViewHolder.java +++ b/app/src/main/java/awais/instagrabber/adapters/viewholder/feed/FeedVideoViewHolder.java @@ -26,6 +26,7 @@ import awais.instagrabber.databinding.ItemFeedVideoBinding; import awais.instagrabber.interfaces.MentionClickListener; import awais.instagrabber.models.FeedModel; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.NumberUtils; import awais.instagrabber.utils.Utils; import static awais.instagrabber.utils.Utils.settingsHelper; @@ -99,7 +100,7 @@ public class FeedVideoViewHolder extends FeedItemViewHolder { binding.itemFeedBottom.btnMute.setVisibility(View.VISIBLE); final ViewGroup.LayoutParams layoutParams = binding.playerView.getLayoutParams(); final int requiredWidth = Utils.displayMetrics.widthPixels; - final int resultingHeight = Utils.getResultingHeight(requiredWidth, feedModel.getImageHeight(), feedModel.getImageWidth()); + final int resultingHeight = NumberUtils.getResultingHeight(requiredWidth, feedModel.getImageHeight(), feedModel.getImageWidth()); layoutParams.width = requiredWidth; layoutParams.height = resultingHeight; binding.playerView.requestLayout(); diff --git a/app/src/main/java/awais/instagrabber/asyncs/CommentAction.java b/app/src/main/java/awais/instagrabber/asyncs/CommentAction.java index 03ba9496..2a5dcaf5 100644 --- a/app/src/main/java/awais/instagrabber/asyncs/CommentAction.java +++ b/app/src/main/java/awais/instagrabber/asyncs/CommentAction.java @@ -11,6 +11,8 @@ import java.net.URL; import awais.instagrabber.models.StoryModel; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; +import awais.instagrabber.utils.NetworkUtils; import awais.instagrabber.utils.Utils; import static awais.instagrabber.utils.Utils.settingsHelper; @@ -38,7 +40,7 @@ public class CommentAction extends AsyncTask { urlConnection.setRequestProperty("User-Agent", Constants.I_USER_AGENT); urlConnection.setUseCaches(false); final String urlParameters = Utils.sign("{\"_csrftoken\":\"" + cookie.split("csrftoken=")[1].split(";")[0] - + "\",\"_uid\":\"" + Utils.getUserIdFromCookie(cookie) + + "\",\"_uid\":\"" + CookieUtils.getUserIdFromCookie(cookie) + "\",\"__uuid\":\"" + settingsHelper.getString(Constants.DEVICE_UUID) + "\",\"recipient_users\":\"[" + storyModel.getUserId() // <- string of array of number (not joking) + "]\"}"); @@ -53,7 +55,7 @@ public class CommentAction extends AsyncTask { wr.close(); urlConnection.connect(); if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { - return new JSONObject(Utils.readFromConnection(urlConnection)).getString("thread_id"); + return new JSONObject(NetworkUtils.readFromConnection(urlConnection)).getString("thread_id"); } } catch (Throwable ex) { diff --git a/app/src/main/java/awais/instagrabber/asyncs/CommentsFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/CommentsFetcher.java index cf043962..6107a038 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/CommentsFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/CommentsFetcher.java @@ -19,7 +19,8 @@ import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.CommentModel; import awais.instagrabber.models.ProfileModel; import awais.instagrabber.utils.Constants; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.NetworkUtils; +import awais.instagrabber.utils.TextUtils; import awaisomereport.LogCollector; import static awais.instagrabber.utils.Utils.logCollector; @@ -57,7 +58,7 @@ public final class CommentsFetcher extends AsyncTask final int childCommentsLen = childCommentModels.length; final CommentModel lastChild = childCommentModels[childCommentsLen - 1]; - if (lastChild != null && lastChild.hasNextPage() && !Utils.isEmpty(lastChild.getEndCursor())) { + if (lastChild != null && lastChild.hasNextPage() && !TextUtils.isEmpty(lastChild.getEndCursor())) { final CommentModel[] remoteChildComments = getChildComments(commentModel.getId()); commentModel.setChildCommentModels(remoteChildComments); lastChild.setPageCursor(false, null); @@ -94,12 +95,12 @@ public final class CommentsFetcher extends AsyncTask if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) break; else { - final JSONObject data = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("data") - .getJSONObject("comment").getJSONObject("edge_threaded_comments"); + final JSONObject data = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONObject("data") + .getJSONObject("comment").getJSONObject("edge_threaded_comments"); final JSONObject pageInfo = data.getJSONObject("page_info"); endCursor = pageInfo.getString("end_cursor"); - if (Utils.isEmpty(endCursor)) endCursor = null; + if (TextUtils.isEmpty(endCursor)) endCursor = null; final JSONArray childComments = data.optJSONArray("edges"); if (childComments != null) { @@ -158,12 +159,12 @@ public final class CommentsFetcher extends AsyncTask if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) break; else { - final JSONObject parentComments = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("data") - .getJSONObject("shortcode_media").getJSONObject("edge_media_to_parent_comment"); + final JSONObject parentComments = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONObject("data") + .getJSONObject("shortcode_media").getJSONObject("edge_media_to_parent_comment"); final JSONObject pageInfo = parentComments.getJSONObject("page_info"); endCursor = pageInfo.optString("end_cursor"); - if (Utils.isEmpty(endCursor)) endCursor = null; + if (TextUtils.isEmpty(endCursor)) endCursor = null; // final boolean containsToken = endCursor.contains("bifilter_token"); // if (!Utils.isEmpty(endCursor) && (containsToken || endCursor.contains("cached_comments_cursor"))) { @@ -216,7 +217,7 @@ public final class CommentsFetcher extends AsyncTask final boolean hasNextPage; if ((tempJsonObject = tempJsonObject.optJSONObject("page_info")) != null) { childEndCursor = tempJsonObject.optString("end_cursor"); - hasNextPage = tempJsonObject.optBoolean("has_next_page", !Utils.isEmpty(childEndCursor)); + hasNextPage = tempJsonObject.optBoolean("has_next_page", !TextUtils.isEmpty(childEndCursor)); } else { childEndCursor = null; hasNextPage = false; diff --git a/app/src/main/java/awais/instagrabber/asyncs/DiscoverFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/DiscoverFetcher.java index 4b16c8e7..c83f2cb0 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/DiscoverFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/DiscoverFetcher.java @@ -21,6 +21,10 @@ import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.DiscoverItemModel; import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.DownloadUtils; +import awais.instagrabber.utils.NetworkUtils; +import awais.instagrabber.utils.ResponseBodyUtils; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import awaisomereport.LogCollector; @@ -75,7 +79,7 @@ public final class DiscoverFetcher extends AsyncTask { final HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection(); if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { - final String json = Utils.readFromConnection(urlConnection); + final String json = NetworkUtils.readFromConnection(urlConnection); // Log.d(TAG, json); final JSONObject timelineFeed = new JSONObject(json).getJSONObject("data") .getJSONObject(Constants.EXTRAS_USER).getJSONObject("edge_web_feed_timeline"); @@ -94,12 +96,12 @@ public final class FeedFetcher extends AsyncTask { final long videoViews = feedItem.optLong("video_view_count", 0); final String displayUrl = feedItem.optString("display_url"); - if (Utils.isEmpty(displayUrl)) continue; + if (TextUtils.isEmpty(displayUrl)) continue; final String resourceUrl; if (isVideo) resourceUrl = feedItem.getString("video_url"); else - resourceUrl = feedItem.has("display_resources") ? Utils.getHighQualityImage(feedItem) : displayUrl; + resourceUrl = feedItem.has("display_resources") ? ResponseBodyUtils.getHighQualityImage(feedItem) : displayUrl; ProfileModel profileModel = null; if (feedItem.has("owner")) { @@ -184,7 +186,7 @@ public final class FeedFetcher extends AsyncTask { sliderItems[j] = new ViewerPostModel( isChildVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE, node.getString(Constants.EXTRAS_ID), - isChildVideo ? node.getString("video_url") : Utils.getHighQualityImage(node), + isChildVideo ? node.getString("video_url") : ResponseBodyUtils.getHighQualityImage(node), null, null, null, diff --git a/app/src/main/java/awais/instagrabber/asyncs/FeedStoriesFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/FeedStoriesFetcher.java index 903486d5..c975dc5d 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/FeedStoriesFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/FeedStoriesFetcher.java @@ -14,7 +14,7 @@ import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.FeedStoryModel; import awais.instagrabber.models.ProfileModel; import awais.instagrabber.utils.Constants; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.NetworkUtils; import awaisomereport.LogCollector.LogFile; import static awais.instagrabber.utils.Utils.logCollector; @@ -39,7 +39,7 @@ public final class FeedStoriesFetcher extends AsyncTask { conn.connect(); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { - final JSONObject data = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("data") - .getJSONObject(Constants.EXTRAS_USER).getJSONObject(isFollowers ? "edge_followed_by" : "edge_follow"); + final JSONObject data = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONObject("data") + .getJSONObject(Constants.EXTRAS_USER).getJSONObject(isFollowers ? "edge_followed_by" : "edge_follow"); final String endCursor; final boolean hasNextPage; diff --git a/app/src/main/java/awais/instagrabber/asyncs/GetActivityAsyncTask.java b/app/src/main/java/awais/instagrabber/asyncs/GetActivityAsyncTask.java index 860015fd..d79f15c1 100644 --- a/app/src/main/java/awais/instagrabber/asyncs/GetActivityAsyncTask.java +++ b/app/src/main/java/awais/instagrabber/asyncs/GetActivityAsyncTask.java @@ -9,7 +9,8 @@ import java.net.HttpURLConnection; import java.net.URL; import awais.instagrabber.utils.Constants; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.NetworkUtils; +import awais.instagrabber.utils.TextUtils; public class GetActivityAsyncTask extends AsyncTask { private static final String TAG = "GetActivityAsyncTask"; @@ -24,7 +25,7 @@ public class GetActivityAsyncTask extends AsyncTask { conn.connect(); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { - final JSONObject user = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("graphql").getJSONObject(Constants.EXTRAS_HASHTAG); + 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")) { diff --git a/app/src/main/java/awais/instagrabber/asyncs/HighlightsFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/HighlightsFetcher.java index b9f487cd..b1e2868e 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/HighlightsFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/HighlightsFetcher.java @@ -15,7 +15,7 @@ import awais.instagrabber.BuildConfig; import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.HighlightModel; import awais.instagrabber.utils.Constants; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.NetworkUtils; public final class HighlightsFetcher extends AsyncTask> { private final String id; @@ -41,7 +41,7 @@ public final class HighlightsFetcher extends AsyncTask highlightModels = new ArrayList<>(); diff --git a/app/src/main/java/awais/instagrabber/asyncs/ImageUploader.java b/app/src/main/java/awais/instagrabber/asyncs/ImageUploader.java index dd4b1cd1..386cb4de 100644 --- a/app/src/main/java/awais/instagrabber/asyncs/ImageUploader.java +++ b/app/src/main/java/awais/instagrabber/asyncs/ImageUploader.java @@ -21,7 +21,8 @@ import java.util.Map; import java.util.UUID; import awais.instagrabber.models.ImageUploadOptions; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.NetworkUtils; +import awais.instagrabber.utils.NumberUtils; public class ImageUploader extends AsyncTask { private static final String TAG = "ImageUploader"; @@ -51,7 +52,7 @@ public class ImageUploader extends AsyncTask headers = new HashMap<>(); final String uploadId = String.valueOf(new Date().getTime()); - final long random = Utils.random(LOWER, UPPER + 1); + final long random = NumberUtils.random(LOWER, UPPER + 1); final String name = String.format("%s_0_%s", uploadId, random); final String waterfallId = options.getWaterfallId() != null ? options.getWaterfallId() : UUID.randomUUID().toString(); headers.put("X-Entity-Type", "image/jpeg"); @@ -68,7 +69,7 @@ public class ImageUploader extends AsyncTask conn.connect(); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { - final JSONObject location = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("graphql") - .getJSONObject(Constants.EXTRAS_LOCATION); + final JSONObject location = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONObject("graphql") + .getJSONObject(Constants.EXTRAS_LOCATION); final JSONObject timelineMedia = location.getJSONObject("edge_location_to_media"); // if (timelineMedia.has("edges")) { diff --git a/app/src/main/java/awais/instagrabber/asyncs/NotificationsFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/NotificationsFetcher.java index d1bdbd22..1cf9b4bf 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/NotificationsFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/NotificationsFetcher.java @@ -14,8 +14,9 @@ import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.NotificationModel; import awais.instagrabber.models.enums.NotificationType; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.LocaleUtils; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.NetworkUtils; import awaisomereport.LogCollector; import static awais.instagrabber.utils.Utils.logCollector; @@ -32,7 +33,7 @@ public final class NotificationsFetcher extends AsyncTask 0 && - (data = media.optJSONObject(0).optJSONObject("node")) != null) { + if (ewaf != null + && (media = ewaf.optJSONArray("edges")) != null + && media.length() > 0 + && media.optJSONObject(0).optJSONObject("node") != null) { mediaLen = media.length(); models = new NotificationModel[mediaLen]; for (int i = 0; i < mediaLen; ++i) { data = media.optJSONObject(i).optJSONObject("node"); - if (Utils.getNotifType(data.getString("__typename")) == null) continue; - models[i] = new NotificationModel(data.getString(Constants.EXTRAS_ID), + if (data == null) continue; + final String type = data.getString("__typename"); + final NotificationType notificationType = NotificationType.valueOfType(type); + if (notificationType == null) continue; + models[i] = new NotificationModel( + data.getString(Constants.EXTRAS_ID), data.optString("text"), // comments or mentions data.getLong("timestamp"), data.getJSONObject("user").getString("username"), data.getJSONObject("user").getString("profile_pic_url"), !data.isNull("media") ? data.getJSONObject("media").getString("shortcode") : null, !data.isNull("media") ? data.getJSONObject("media").getString("thumbnail_src") : null, - Utils.getNotifType(data.getString("__typename"))); + notificationType); } } - if (efr != null && (media = efr.optJSONArray("edges")) != null && media.length() > 0 && - (data = media.optJSONObject(0).optJSONObject("node")) != null) { + if (efr != null + && (media = efr.optJSONArray("edges")) != null + && media.length() > 0 + && media.optJSONObject(0).optJSONObject("node") != null) { reqLen = media.length(); req = new NotificationModel[reqLen]; for (int i = 0; i < reqLen; ++i) { data = media.optJSONObject(i).optJSONObject("node"); + if (data == null) continue; req[i] = new NotificationModel(data.getString(Constants.EXTRAS_ID), - data.optString("full_name"), 0L, data.getString("username"), - data.getString("profile_pic_url"), null, null, NotificationType.REQUEST); + data.optString("full_name"), 0L, data.getString("username"), + data.getString("profile_pic_url"), null, null, NotificationType.REQUEST); } } diff --git a/app/src/main/java/awais/instagrabber/asyncs/PostFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/PostFetcher.java index c58fc0e8..71b69c54 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/PostFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/PostFetcher.java @@ -16,6 +16,11 @@ import awais.instagrabber.models.ProfileModel; import awais.instagrabber.models.ViewerPostModel; import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; +import awais.instagrabber.utils.DownloadUtils; +import awais.instagrabber.utils.NetworkUtils; +import awais.instagrabber.utils.ResponseBodyUtils; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import awaisomereport.LogCollector; @@ -38,7 +43,7 @@ public final class PostFetcher extends AsyncTask @Override protected ViewerPostModel[] doInBackground(final Void... voids) { ViewerPostModel[] result = null; - Utils.setupCookies(Utils.settingsHelper.getString(Constants.COOKIE)); // <- direct download + CookieUtils.setupCookies(Utils.settingsHelper.getString(Constants.COOKIE)); // <- direct download try { final HttpURLConnection conn = (HttpURLConnection) new URL("https://www.instagram.com/p/" + shortCode + "/?__a=1").openConnection(); conn.setUseCaches(false); @@ -46,8 +51,8 @@ public final class PostFetcher extends AsyncTask if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { - final JSONObject media = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("graphql") - .getJSONObject("shortcode_media"); + final JSONObject media = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONObject("graphql") + .getJSONObject("shortcode_media"); ProfileModel profileModel = null; if (media.has("owner")) { @@ -82,7 +87,7 @@ public final class PostFetcher extends AsyncTask (Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/" + username) : "")); - if (!Utils.isEmpty(customPath)) customDir = new File(customPath); + if (!TextUtils.isEmpty(customPath)) customDir = new File(customPath); } final long timestamp = media.getLong("taken_at_timestamp"); @@ -116,9 +121,9 @@ public final class PostFetcher extends AsyncTask final ViewerPostModel postModel = new ViewerPostModel( mediaItemType, media.getString(Constants.EXTRAS_ID), - isVideo ? media.getString("video_url") : Utils.getHighQualityImage(media), + isVideo ? media.getString("video_url") : ResponseBodyUtils.getHighQualityImage(media), shortCode, - Utils.isEmpty(postCaption) ? null : postCaption, + TextUtils.isEmpty(postCaption) ? null : postCaption, profileModel, isVideo && media.has("video_view_count") ? media.getLong("video_view_count") : -1, timestamp, media.getBoolean("viewer_has_liked"), media.getBoolean("viewer_has_saved"), @@ -130,7 +135,7 @@ public final class PostFetcher extends AsyncTask postModel.setCommentsCount(commentsCount); - Utils.checkExistence(downloadDir, customDir, false, postModel); + DownloadUtils.checkExistence(downloadDir, customDir, false, postModel); result = new ViewerPostModel[]{postModel}; @@ -145,7 +150,7 @@ public final class PostFetcher extends AsyncTask postModels[i] = new ViewerPostModel( isChildVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE, media.getString(Constants.EXTRAS_ID), - isChildVideo ? node.getString("video_url") : Utils.getHighQualityImage(node), + isChildVideo ? node.getString("video_url") : ResponseBodyUtils.getHighQualityImage(node), node.getString(Constants.EXTRAS_SHORTCODE), postCaption, profileModel, @@ -158,7 +163,7 @@ public final class PostFetcher extends AsyncTask media.getJSONObject("location").optString("slug"))); postModels[i].setSliderDisplayUrl(node.getString("display_url")); - Utils.checkExistence(downloadDir, customDir, true, postModels[i]); + DownloadUtils.checkExistence(downloadDir, customDir, true, postModels[i]); } postModels[0].setCommentsCount(commentsCount); diff --git a/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java index 97efc042..0ac8ed24 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/PostsFetcher.java @@ -17,6 +17,9 @@ import awais.instagrabber.models.PostModel; import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.models.enums.PostItemType; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.DownloadUtils; +import awais.instagrabber.utils.NetworkUtils; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import awaisomereport.LogCollector; @@ -92,14 +95,14 @@ public final class PostsFetcher extends AsyncTask { (Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/" + username) : "")); - if (!Utils.isEmpty(customPath)) customDir = new File(customPath); + if (!TextUtils.isEmpty(customPath)) customDir = new File(customPath); } final boolean isHashtag = type == PostItemType.HASHTAG; final boolean isLocation = type == PostItemType.LOCATION; final boolean isSaved = type == PostItemType.SAVED; final boolean isTagged = type == PostItemType.TAGGED; - final JSONObject mediaPosts = new JSONObject(Utils.readFromConnection(conn)) + final JSONObject mediaPosts = new JSONObject(NetworkUtils.readFromConnection(conn)) .getJSONObject("data") .getJSONObject(isHashtag ? Constants.EXTRAS_HASHTAG @@ -143,7 +146,7 @@ public final class PostsFetcher extends AsyncTask { mediaNode.getLong("taken_at_timestamp"), mediaNode.optBoolean("viewer_has_liked"), mediaNode.optBoolean("viewer_has_saved"), mediaNode.getJSONObject("edge_liked_by").getLong("count")); - Utils.checkExistence(downloadDir, customDir, isSlider, models[i]); + DownloadUtils.checkExistence(downloadDir, customDir, isSlider, models[i]); } if (models.length != 0 && models[models.length - 1] != null) diff --git a/app/src/main/java/awais/instagrabber/asyncs/ProfileFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/ProfileFetcher.java index 189f48e8..5bae0f88 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/ProfileFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/ProfileFetcher.java @@ -15,7 +15,8 @@ import awais.instagrabber.BuildConfig; import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.ProfileModel; import awais.instagrabber.utils.Constants; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.NetworkUtils; +import awais.instagrabber.utils.TextUtils; import awaisomereport.LogCollector; import static awais.instagrabber.utils.Utils.logCollector; @@ -40,7 +41,7 @@ public final class ProfileFetcher extends AsyncTask { conn.connect(); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { - final JSONObject user = new JSONObject(Utils.readFromConnection(conn)).getJSONObject("graphql").getJSONObject(Constants.EXTRAS_USER); + final JSONObject user = new JSONObject(NetworkUtils.readFromConnection(conn)).getJSONObject("graphql").getJSONObject(Constants.EXTRAS_USER); boolean isPrivate = user.getBoolean("is_private"); boolean reallyPrivate = isPrivate; @@ -51,7 +52,7 @@ public final class ProfileFetcher extends AsyncTask { } String url = user.optString("external_url"); - if (Utils.isEmpty(url)) url = null; + if (TextUtils.isEmpty(url)) url = null; result = new ProfileModel(isPrivate, reallyPrivate, diff --git a/app/src/main/java/awais/instagrabber/asyncs/ProfilePictureFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/ProfilePictureFetcher.java index 46d93041..6fe750a1 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/ProfilePictureFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/ProfilePictureFetcher.java @@ -15,6 +15,8 @@ import java.net.URL; import awais.instagrabber.BuildConfig; import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.NetworkUtils; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import awaisomereport.LogCollector; @@ -45,26 +47,26 @@ public final class ProfilePictureFetcher extends AsyncTask { conn.setRequestMethod("GET"); conn.setRequestProperty("User-Agent", Constants.USER_AGENT); - final String result = conn.getResponseCode() == HttpURLConnection.HTTP_OK ? Utils.readFromConnection(conn) : null; + final String result = conn.getResponseCode() == HttpURLConnection.HTTP_OK ? NetworkUtils.readFromConnection(conn) : null; conn.disconnect(); - if (!Utils.isEmpty(result)) { + if (!TextUtils.isEmpty(result)) { JSONObject data = new JSONObject(result).getJSONObject("user"); if (data.has("hd_profile_pic_url_info")) out = data.getJSONObject("hd_profile_pic_url_info").optString("url"); } - if (Utils.isEmpty(out) && Utils.settingsHelper.getBoolean(Constants.INSTADP)) { + if (TextUtils.isEmpty(out) && Utils.settingsHelper.getBoolean(Constants.INSTADP)) { final HttpURLConnection backup = (HttpURLConnection) new URL("https://instadp.com/fullsize/" + userName).openConnection(); backup.setUseCaches(false); backup.setRequestMethod("GET"); backup.setRequestProperty("User-Agent", Constants.A_USER_AGENT); - final String instadp = backup.getResponseCode() == HttpURLConnection.HTTP_OK ? Utils.readFromConnection(backup) : null; + final String instadp = backup.getResponseCode() == HttpURLConnection.HTTP_OK ? NetworkUtils.readFromConnection(backup) : null; backup.disconnect(); - if (!Utils.isEmpty(instadp)) { + if (!TextUtils.isEmpty(instadp)) { final Document doc = Jsoup.parse(instadp); boolean fallback = false; @@ -86,7 +88,7 @@ public final class ProfilePictureFetcher extends AsyncTask { } } } - if (Utils.isEmpty(out)) out = picUrl; + if (TextUtils.isEmpty(out)) out = picUrl; } catch (final Exception e) { if (logCollector != null) logCollector.appendException(e, LogCollector.LogFile.ASYNC_PROFILE_PICTURE_FETCHER, "doInBackground"); diff --git a/app/src/main/java/awais/instagrabber/asyncs/QuizAction.java b/app/src/main/java/awais/instagrabber/asyncs/QuizAction.java index d8a61131..4042b875 100644 --- a/app/src/main/java/awais/instagrabber/asyncs/QuizAction.java +++ b/app/src/main/java/awais/instagrabber/asyncs/QuizAction.java @@ -13,6 +13,7 @@ import java.util.UUID; import awais.instagrabber.models.StoryModel; import awais.instagrabber.models.stickers.QuizModel; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.Utils; import static awais.instagrabber.utils.Utils.settingsHelper; @@ -43,7 +44,7 @@ public class QuizAction extends AsyncTask { JSONObject ogBody = new JSONObject("{\"client_context\":\"" + UUID.randomUUID().toString() + "\",\"mutation_token\":\"" + UUID.randomUUID().toString() + "\",\"_csrftoken\":\"" + cookie.split("csrftoken=")[1].split(";")[0] - + "\",\"_uid\":\"" + Utils.getUserIdFromCookie(cookie) + + "\",\"_uid\":\"" + CookieUtils.getUserIdFromCookie(cookie) + "\",\"__uuid\":\"" + settingsHelper.getString(Constants.DEVICE_UUID) + "\"}"); ogBody.put("answer", String.valueOf(choice)); diff --git a/app/src/main/java/awais/instagrabber/asyncs/RespondAction.java b/app/src/main/java/awais/instagrabber/asyncs/RespondAction.java index 96bf2d0f..836d6b76 100644 --- a/app/src/main/java/awais/instagrabber/asyncs/RespondAction.java +++ b/app/src/main/java/awais/instagrabber/asyncs/RespondAction.java @@ -13,6 +13,7 @@ import java.util.UUID; import awais.instagrabber.models.StoryModel; import awais.instagrabber.models.stickers.QuestionModel; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.Utils; import static awais.instagrabber.utils.Utils.settingsHelper; @@ -42,7 +43,7 @@ public class RespondAction extends AsyncTask { final JSONObject ogbody = new JSONObject("{\"client_context\":\"" + UUID.randomUUID().toString() + "\",\"mutation_token\":\"" + UUID.randomUUID().toString() + "\",\"_csrftoken\":\"" + cookie.split("csrftoken=")[1].split(";")[0] - + "\",\"_uid\":\"" + Utils.getUserIdFromCookie(cookie) + + "\",\"_uid\":\"" + CookieUtils.getUserIdFromCookie(cookie) + "\",\"__uuid\":\"" + settingsHelper.getString(Constants.DEVICE_UUID) + "\"}"); String choice = rawChoice[0].replaceAll("\"", ("\\\"")); diff --git a/app/src/main/java/awais/instagrabber/asyncs/SeenAction.java b/app/src/main/java/awais/instagrabber/asyncs/SeenAction.java index 39a798ae..7656369d 100644 --- a/app/src/main/java/awais/instagrabber/asyncs/SeenAction.java +++ b/app/src/main/java/awais/instagrabber/asyncs/SeenAction.java @@ -8,7 +8,7 @@ import java.net.HttpURLConnection; import java.net.URL; import awais.instagrabber.models.StoryModel; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.NetworkUtils; public class SeenAction extends AsyncTask { private static final String TAG = "SeenAction"; @@ -41,7 +41,7 @@ public class SeenAction extends AsyncTask { wr.flush(); wr.close(); urlConnection.connect(); - Log.d(TAG, urlConnection.getResponseCode() + " " + Utils.readFromConnection(urlConnection)); + Log.d(TAG, urlConnection.getResponseCode() + " " + NetworkUtils.readFromConnection(urlConnection)); urlConnection.disconnect(); } catch (Throwable ex) { Log.e(TAG, "Error", ex); diff --git a/app/src/main/java/awais/instagrabber/asyncs/SuggestionsFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/SuggestionsFetcher.java index c4587ce7..21b77ac8 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/SuggestionsFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/SuggestionsFetcher.java @@ -17,8 +17,8 @@ import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.SuggestionModel; import awais.instagrabber.models.enums.SuggestionType; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.NetworkUtils; import awais.instagrabber.utils.UrlEncoder; -import awais.instagrabber.utils.Utils; public final class SuggestionsFetcher extends AsyncTask { private final FetchListener fetchListener; @@ -43,7 +43,7 @@ public final class SuggestionsFetcher extends AsyncTask { private final FetchListener fetchListener; @@ -36,7 +36,7 @@ public final class UsernameFetcher extends AsyncTask { final JSONObject user; if (conn.getResponseCode() == HttpURLConnection.HTTP_OK && - (user = new JSONObject(Utils.readFromConnection(conn)).optJSONObject(Constants.EXTRAS_USER)) != null) + (user = new JSONObject(NetworkUtils.readFromConnection(conn)).optJSONObject(Constants.EXTRAS_USER)) != null) result = user.getString(Constants.EXTRAS_USERNAME); conn.disconnect(); diff --git a/app/src/main/java/awais/instagrabber/asyncs/direct_messages/DirectMessageInboxThreadFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/direct_messages/DirectMessageInboxThreadFetcher.java index 36ed285e..1fe89f8f 100644 --- a/app/src/main/java/awais/instagrabber/asyncs/direct_messages/DirectMessageInboxThreadFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/direct_messages/DirectMessageInboxThreadFetcher.java @@ -18,7 +18,9 @@ import awais.instagrabber.models.direct_messages.InboxThreadModel; import awais.instagrabber.models.enums.UserInboxDirection; import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.LocaleUtils; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.NetworkUtils; +import awais.instagrabber.utils.ResponseBodyUtils; +import awais.instagrabber.utils.TextUtils; import static awais.instagrabber.utils.Utils.logCollector; import static awaisomereport.LogCollector.LogFile; @@ -48,10 +50,10 @@ public final class DirectMessageInboxThreadFetcher extends AsyncTask queryParamsMap = new HashMap<>(); queryParamsMap.put("visual_message_return_type", "unseen"); if (direction != null) queryParamsMap.put("direction", direction.getValue()); - if (!Utils.isEmpty(endCursor)) { + if (!TextUtils.isEmpty(endCursor)) { queryParamsMap.put("cursor", endCursor); } - final String queryString = Utils.getQueryString(queryParamsMap); + final String queryString = NetworkUtils.getQueryString(queryParamsMap); final String url = "https://i.instagram.com/api/v1/direct_v2/threads/" + id + "/?" + queryString; try { final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); @@ -60,8 +62,8 @@ public final class DirectMessageInboxThreadFetcher extends AsyncTask form = new HashMap<>(); - form.put("_csrftoken", Utils.getCsrfTokenFromCookie(cookie)); - form.put("_uid", Utils.getUserIdFromCookie(cookie)); + form.put("_csrftoken", CookieUtils.getCsrfTokenFromCookie(cookie)); + form.put("_uid", CookieUtils.getUserIdFromCookie(cookie)); form.put("__uuid", settingsHelper.getString(Constants.DEVICE_UUID)); form.put("client_context", cc); form.put("mutation_token", cc); diff --git a/app/src/main/java/awais/instagrabber/asyncs/direct_messages/InboxFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/direct_messages/InboxFetcher.java index c875fd61..355b3ed1 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/direct_messages/InboxFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/direct_messages/InboxFetcher.java @@ -20,7 +20,9 @@ import awais.instagrabber.models.direct_messages.InboxModel; import awais.instagrabber.models.direct_messages.InboxThreadModel; import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.LocaleUtils; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.NetworkUtils; +import awais.instagrabber.utils.ResponseBodyUtils; +import awais.instagrabber.utils.TextUtils; import static awais.instagrabber.utils.Utils.logCollector; import static awaisomereport.LogCollector.LogFile; @@ -32,7 +34,7 @@ public final class InboxFetcher extends AsyncTask { private final FetchListener fetchListener; public InboxFetcher(final String endCursor, final FetchListener fetchListener) { - this.endCursor = Utils.isEmpty(endCursor) ? "" : "?cursor=" + endCursor; + this.endCursor = TextUtils.isEmpty(endCursor) ? "" : "?cursor=" + endCursor; this.fetchListener = fetchListener; } @@ -63,7 +65,7 @@ public final class InboxFetcher extends AsyncTask { conn.disconnect(); return null; } - JSONObject data = new JSONObject(Utils.readFromConnection(conn)); + JSONObject data = new JSONObject(NetworkUtils.readFromConnection(conn)); // try (FileWriter fileWriter = new FileWriter(new File("/sdcard/test.json"))) { // fileWriter.write(data.toString(2)); // } @@ -88,7 +90,7 @@ public final class InboxFetcher extends AsyncTask { inboxThreadModels = new InboxThreadModel[threadsLen]; for (int i = 0; i < threadsLen; ++i) - inboxThreadModels[i] = Utils.createInboxThreadModel(threadsArray.getJSONObject(i), false); + inboxThreadModels[i] = ResponseBodyUtils.createInboxThreadModel(threadsArray.getJSONObject(i), false); } result = new InboxModel(hasOlder, hasPendingTopRequests, diff --git a/app/src/main/java/awais/instagrabber/asyncs/i/iLikedFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/i/iLikedFetcher.java index 85a5247b..c631018d 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/i/iLikedFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/i/iLikedFetcher.java @@ -16,6 +16,10 @@ import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.PostModel; import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.DownloadUtils; +import awais.instagrabber.utils.NetworkUtils; +import awais.instagrabber.utils.ResponseBodyUtils; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import awaisomereport.LogCollector; @@ -50,7 +54,7 @@ public final class iLikedFetcher extends AsyncTask { conn.connect(); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { - final JSONObject body = new JSONObject(Utils.readFromConnection(conn)); + final JSONObject body = new JSONObject(NetworkUtils.readFromConnection(conn)); final String endCursor; final boolean hasNextPage; @@ -77,12 +81,12 @@ public final class iLikedFetcher extends AsyncTask { else itemType = MediaItemType.MEDIA_TYPE_IMAGE; models[i] = new PostModel(itemType, mediaNode.getString(Constants.EXTRAS_ID), - isSlider - ? Utils.getHighQualityImage(mediaNode.getJSONArray("carousel_media").getJSONObject(0)) - : Utils.getHighQualityImage(mediaNode), - isSlider - ? Utils.getLowQualityImage(mediaNode.getJSONArray("carousel_media").getJSONObject(0)) - : Utils.getLowQualityImage(mediaNode), + isSlider + ? ResponseBodyUtils.getHighQualityImage(mediaNode.getJSONArray("carousel_media").getJSONObject(0)) + : ResponseBodyUtils.getHighQualityImage(mediaNode), + isSlider + ? ResponseBodyUtils.getLowQualityImage(mediaNode.getJSONArray("carousel_media").getJSONObject(0)) + : ResponseBodyUtils.getLowQualityImage(mediaNode), mediaNode.getString("code"), mediaNode.isNull("caption") ? null : mediaNode.getJSONObject("caption").optString("text"), mediaNode.getLong("taken_at"), true, @@ -95,9 +99,9 @@ public final class iLikedFetcher extends AsyncTask { if (Utils.settingsHelper.getBoolean(FOLDER_SAVE_TO)) { final String customPath = Utils.settingsHelper.getString(FOLDER_PATH + (Utils.settingsHelper.getBoolean(DOWNLOAD_USER_FOLDER) ? ("/"+username) : "")); - if (!Utils.isEmpty(customPath)) customDir = new File(customPath); + if (!TextUtils.isEmpty(customPath)) customDir = new File(customPath); } - Utils.checkExistence(downloadDir, customDir, isSlider, models[i]); + DownloadUtils.checkExistence(downloadDir, customDir, isSlider, models[i]); } if (models[models.length - 1] != null) diff --git a/app/src/main/java/awais/instagrabber/asyncs/i/iPostFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/i/iPostFetcher.java index c022a80f..dae6f368 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/i/iPostFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/i/iPostFetcher.java @@ -17,6 +17,10 @@ import awais.instagrabber.models.ProfileModel; import awais.instagrabber.models.ViewerPostModel; import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.DownloadUtils; +import awais.instagrabber.utils.NetworkUtils; +import awais.instagrabber.utils.ResponseBodyUtils; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import awaisomereport.LogCollector; @@ -46,7 +50,7 @@ public final class iPostFetcher extends AsyncTask conn.connect(); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { - final JSONObject media = new JSONObject(Utils.readFromConnection(conn)) + final JSONObject media = new JSONObject(NetworkUtils.readFromConnection(conn)) .getJSONArray("items") .getJSONObject(0); ProfileModel profileModel = null; @@ -94,7 +98,7 @@ public final class iPostFetcher extends AsyncTask if (Utils.settingsHelper.getBoolean(FOLDER_SAVE_TO)) { final String customPath = Utils.settingsHelper.getString(FOLDER_PATH) + (shouldDownloadToUserFolder ? "/" + profileModel.getUsername() : ""); - if (!Utils.isEmpty(customPath)) customDir = new File(customPath); + if (!TextUtils.isEmpty(customPath)) customDir = new File(customPath); } final long timestamp = media.getLong("taken_at"); @@ -130,10 +134,10 @@ public final class iPostFetcher extends AsyncTask final ViewerPostModel postModel = new ViewerPostModel( mediaItemType, media.getString(Constants.EXTRAS_ID), - isVideo ? Utils.getHighQualityPost(media.optJSONArray("video_versions"), true, true, false) - : Utils.getHighQualityImage(media), + isVideo ? ResponseBodyUtils.getHighQualityPost(media.optJSONArray("video_versions"), true, true, false) + : ResponseBodyUtils.getHighQualityImage(media), media.getString("code"), - Utils.isEmpty(postCaption) ? null : postCaption, + TextUtils.isEmpty(postCaption) ? null : postCaption, profileModel, isVideo && media.has("view_count") ? media.getLong("view_count") : -1, timestamp, media.optBoolean("has_liked"), @@ -144,7 +148,7 @@ public final class iPostFetcher extends AsyncTask postModel.setCommentsCount(commentsCount); - Utils.checkExistence(downloadDir, customDir, false, postModel); + DownloadUtils.checkExistence(downloadDir, customDir, false, postModel); result = new ViewerPostModel[]{postModel}; @@ -160,8 +164,8 @@ public final class iPostFetcher extends AsyncTask isChildVideo ? MediaItemType.MEDIA_TYPE_VIDEO : MediaItemType.MEDIA_TYPE_IMAGE, media.getString(Constants.EXTRAS_ID), - isChildVideo ? Utils.getHighQualityPost(node.optJSONArray("video_versions"), true, true, false) - : Utils.getHighQualityImage(node), + isChildVideo ? ResponseBodyUtils.getHighQualityPost(node.optJSONArray("video_versions"), true, true, false) + : ResponseBodyUtils.getHighQualityImage(node), media.getString("code"), postCaption, profileModel, @@ -171,8 +175,8 @@ public final class iPostFetcher extends AsyncTask media.getLong("like_count"), locationName, locationId); - postModels[i].setSliderDisplayUrl(Utils.getHighQualityImage(node)); - Utils.checkExistence(downloadDir, customDir, true, postModels[i]); + postModels[i].setSliderDisplayUrl(ResponseBodyUtils.getHighQualityImage(node)); + DownloadUtils.checkExistence(downloadDir, customDir, true, postModels[i]); } postModels[0].setCommentsCount(commentsCount); diff --git a/app/src/main/java/awais/instagrabber/asyncs/i/iStoryStatusFetcher.java b/app/src/main/java/awais/instagrabber/asyncs/i/iStoryStatusFetcher.java index f584df06..2524070e 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/i/iStoryStatusFetcher.java +++ b/app/src/main/java/awais/instagrabber/asyncs/i/iStoryStatusFetcher.java @@ -19,7 +19,8 @@ import awais.instagrabber.models.stickers.QuizModel; import awais.instagrabber.models.stickers.SwipeUpModel; import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.LocaleUtils; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.NetworkUtils; +import awais.instagrabber.utils.ResponseBodyUtils; import awaisomereport.LogCollector; import static awais.instagrabber.utils.Utils.logCollector; @@ -90,7 +91,7 @@ public final class iStoryStatusFetcher extends AsyncTask> extends BaseControllerListener { private static final String TAG = "ImageResizingController"; @@ -34,7 +34,7 @@ public class ImageResizingControllerListener { - if (ContextCompat.checkSelfPermission(requireContext(), Utils.PERMS[0]) == PackageManager.PERMISSION_GRANTED) { + if (ContextCompat.checkSelfPermission(requireContext(), DownloadUtils.PERMS[0]) == PackageManager.PERMISSION_GRANTED) { downloadProfilePicture(); return; } - requestPermissions(Utils.PERMS, 8020); + requestPermissions(DownloadUtils.PERMS, 8020); }); } @@ -106,7 +107,7 @@ public class ProfilePicDialogFragment extends DialogFragment { private void fetchPhoto() { final FetchListener fetchListener = profileUrl -> { url = profileUrl; - if (Utils.isEmpty(url)) { + if (TextUtils.isEmpty(url)) { url = fallbackUrl; } final DraweeController controller = Fresco diff --git a/app/src/main/java/awais/instagrabber/dialogs/QuickAccessDialog.java b/app/src/main/java/awais/instagrabber/dialogs/QuickAccessDialog.java index 39054fce..e5cb4a69 100755 --- a/app/src/main/java/awais/instagrabber/dialogs/QuickAccessDialog.java +++ b/app/src/main/java/awais/instagrabber/dialogs/QuickAccessDialog.java @@ -23,7 +23,10 @@ import java.util.ArrayList; import awais.instagrabber.R; import awais.instagrabber.adapters.SimpleAdapter; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.DataBox; +import awais.instagrabber.utils.DownloadUtils; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import static awais.instagrabber.utils.Utils.settingsHelper; @@ -58,7 +61,7 @@ public final class QuickAccessDialog extends BottomSheetDialogFragment implement btnFavorite = contentView.findViewById(R.id.btnFavorite); btnImportExport = contentView.findViewById(R.id.importExport); - isQuery = !Utils.isEmpty(userQuery); + isQuery = !TextUtils.isEmpty(userQuery); btnFavorite.setVisibility(isQuery ? View.VISIBLE : View.GONE); Utils.setTooltipText(btnImportExport, R.string.import_export); @@ -75,12 +78,12 @@ public final class QuickAccessDialog extends BottomSheetDialogFragment implement rvFavorites.setAdapter(favoritesAdapter); final String cookieStr = settingsHelper.getString(Constants.COOKIE); - if (!Utils.isEmpty(cookieStr) + if (!TextUtils.isEmpty(cookieStr) || Utils.dataBox.getCookieCount() > 0 // fallback for export / import ) { rvQuickAccess.addItemDecoration(itemDecoration); final ArrayList allCookies = Utils.dataBox.getAllCookies(); - if (!Utils.isEmpty(cookieStr) && allCookies != null) { + if (!TextUtils.isEmpty(cookieStr) && allCookies != null) { for (final DataBox.CookieModel cookie : allCookies) { if (cookieStr.equals(cookie.getCookie())) { cookie.setSelected(true); @@ -106,8 +109,8 @@ public final class QuickAccessDialog extends BottomSheetDialogFragment implement favoritesAdapter.setItems(Utils.dataBox.getAllFavorites()); } } else if (v == btnImportExport) { - if (ContextCompat.checkSelfPermission(activity, Utils.PERMS[0]) == PackageManager.PERMISSION_DENIED) - requestPermissions(Utils.PERMS, 6007); + if (ContextCompat.checkSelfPermission(activity, DownloadUtils.PERMS[0]) == PackageManager.PERMISSION_DENIED) + requestPermissions(DownloadUtils.PERMS, 6007); else Utils.showImportExportDialog(v.getContext()); } else if (tag instanceof DataBox.FavoriteModel) { @@ -120,7 +123,7 @@ public final class QuickAccessDialog extends BottomSheetDialogFragment implement final DataBox.CookieModel cookieModel = (DataBox.CookieModel) tag; if (!cookieModel.isSelected()) { settingsHelper.putString(Constants.COOKIE, cookieModel.getCookie()); - Utils.setupCookies(cookieModel.getCookie()); + CookieUtils.setupCookies(cookieModel.getCookie()); cookieChanged = true; } dismiss(); diff --git a/app/src/main/java/awais/instagrabber/dialogs/SettingsDialog.java b/app/src/main/java/awais/instagrabber/dialogs/SettingsDialog.java index 02ac22d8..cd4c14fc 100755 --- a/app/src/main/java/awais/instagrabber/dialogs/SettingsDialog.java +++ b/app/src/main/java/awais/instagrabber/dialogs/SettingsDialog.java @@ -30,8 +30,11 @@ import awais.instagrabber.BuildConfig; import awais.instagrabber.R; import awais.instagrabber.activities.Login; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.DirectoryChooser; +import awais.instagrabber.utils.DownloadUtils; import awais.instagrabber.utils.LocaleUtils; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import awaisomereport.CrashReporter; @@ -118,7 +121,7 @@ public final class SettingsDialog extends BottomSheetDialogFragment implements V btnTimeSettings.setOnClickListener(this); btnPrivacy.setOnClickListener(this); - if (Utils.isEmpty(settingsHelper.getString(Constants.COOKIE))) btnLogout.setEnabled(false); + if (TextUtils.isEmpty(settingsHelper.getString(Constants.COOKIE))) btnLogout.setEnabled(false); spAppTheme = contentView.findViewById(R.id.spAppTheme); currentTheme = Integer.parseInt(settingsHelper.getString(APP_THEME)); @@ -208,13 +211,13 @@ public final class SettingsDialog extends BottomSheetDialogFragment implements V startActivity(new Intent(v.getContext(), Login.class)); somethingChanged = true; } else if (v == btnLogout) { - Utils.setupCookies("LOGOUT"); + CookieUtils.setupCookies("LOGOUT"); settingsHelper.putString(Constants.COOKIE, ""); somethingChanged = true; this.dismiss(); } else if (v == btnImportExport) { - if (ContextCompat.checkSelfPermission(activity, Utils.PERMS[0]) == PackageManager.PERMISSION_DENIED) - requestPermissions(Utils.PERMS, 6007); + if (ContextCompat.checkSelfPermission(activity, DownloadUtils.PERMS[0]) == PackageManager.PERMISSION_DENIED) + requestPermissions(DownloadUtils.PERMS, 6007); else Utils.showImportExportDialog(activity); } else if (v == btnTimeSettings) { new TimeSettingsDialog(settingsHelper.getBoolean(Constants.CUSTOM_DATE_TIME_FORMAT_ENABLED), @@ -242,8 +245,8 @@ public final class SettingsDialog extends BottomSheetDialogFragment implements V } else if (v == btnReport) { CrashReporter.get(activity.getApplication()).zipLogs().startCrashEmailIntent(activity, true); } else if (v == btnSaveTo) { - if (ContextCompat.checkSelfPermission(activity, Utils.PERMS[0]) == PackageManager.PERMISSION_DENIED) - requestPermissions(Utils.PERMS, 6200); + if (ContextCompat.checkSelfPermission(activity, DownloadUtils.PERMS[0]) == PackageManager.PERMISSION_DENIED) + requestPermissions(DownloadUtils.PERMS, 6200); else showDirectoryChooser(); } else if (v == btnPrivacy) { final Intent intent = new Intent(Intent.ACTION_VIEW); diff --git a/app/src/main/java/awais/instagrabber/dialogs/TimeSettingsDialog.java b/app/src/main/java/awais/instagrabber/dialogs/TimeSettingsDialog.java index b0a9aa85..9a371db2 100755 --- a/app/src/main/java/awais/instagrabber/dialogs/TimeSettingsDialog.java +++ b/app/src/main/java/awais/instagrabber/dialogs/TimeSettingsDialog.java @@ -23,7 +23,7 @@ import java.util.GregorianCalendar; import awais.instagrabber.databinding.DialogTimeSettingsBinding; import awais.instagrabber.utils.LocaleUtils; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.TextUtils; public final class TimeSettingsDialog extends DialogFragment implements AdapterView.OnItemSelectedListener, CompoundButton.OnCheckedChangeListener, View.OnClickListener, TextWatcher { @@ -89,7 +89,7 @@ public final class TimeSettingsDialog extends DialogFragment implements AdapterV final boolean isSwapTime = !timeSettingsBinding.cbSwapTimeDate.isChecked(); selectedFormat = (isSwapTime ? timeStr : dateStr) - + (Utils.isEmpty(sepStr) || timeSettingsBinding.spSeparator.getSelectedItemPosition() == 0 ? " " : " '" + sepStr + "' ") + + (TextUtils.isEmpty(sepStr) || timeSettingsBinding.spSeparator.getSelectedItemPosition() == 0 ? " " : " '" + sepStr + "' ") + (isSwapTime ? dateStr : timeStr); timeSettingsBinding.btnConfirm.setEnabled(true); @@ -102,7 +102,7 @@ public final class TimeSettingsDialog extends DialogFragment implements AdapterV try { //noinspection ConstantConditions final String string = timeSettingsBinding.etCustomFormat.getText().toString(); - if (Utils.isEmpty(string)) throw new NullPointerException(); + if (TextUtils.isEmpty(string)) throw new NullPointerException(); currentFormat = new SimpleDateFormat(string, LocaleUtils.getCurrentLocale()); final String format = currentFormat.format(magicDate); timeSettingsBinding.timePreview.setText(format); diff --git a/app/src/main/java/awais/instagrabber/directdownload/DirectDownload.java b/app/src/main/java/awais/instagrabber/directdownload/DirectDownload.java index 31794555..5e1a35b0 100755 --- a/app/src/main/java/awais/instagrabber/directdownload/DirectDownload.java +++ b/app/src/main/java/awais/instagrabber/directdownload/DirectDownload.java @@ -33,11 +33,12 @@ import awais.instagrabber.models.ViewerPostModel; import awais.instagrabber.models.enums.DownloadMethod; import awais.instagrabber.models.enums.IntentModelType; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.DownloadUtils; import awais.instagrabber.utils.IntentUtils; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.TextUtils; -import static awais.instagrabber.utils.Utils.CHANNEL_ID; -import static awais.instagrabber.utils.Utils.CHANNEL_NAME; +import static awais.instagrabber.utils.Constants.CHANNEL_ID; +import static awais.instagrabber.utils.Constants.CHANNEL_NAME; import static awais.instagrabber.utils.Utils.isChannelCreated; import static awais.instagrabber.utils.Utils.notificationManager; @@ -84,14 +85,14 @@ public final class DirectDownload extends Activity { handler.removeCallbacks(this); } }); - ActivityCompat.requestPermissions(this, Utils.PERMS, 8020); + ActivityCompat.requestPermissions(this, DownloadUtils.PERMS, 8020); } finish(); } private synchronized void doDownload() { final String action = intent.getAction(); - if (!Utils.isEmpty(action) && !Intent.ACTION_MAIN.equals(action)) { + if (!TextUtils.isEmpty(action) && !Intent.ACTION_MAIN.equals(action)) { boolean error = true; String data = null; @@ -109,7 +110,7 @@ public final class DirectDownload extends Activity { if (intentData != null) data = intentData.toString(); } - if (data != null && !Utils.isEmpty(data)) { + if (data != null && !TextUtils.isEmpty(data)) { final IntentModel model = IntentUtils.parseUrl(data); if (model != null && model.getType() == IntentModelType.POST) { final String text = model.getText(); @@ -137,8 +138,8 @@ public final class DirectDownload extends Activity { if (notificationManager != null) notificationManager.cancel(1900000000); if (result != null) { if (result.length == 1) { - Utils.batchDownload(context, result[0].getProfileModel().getUsername(), DownloadMethod.DOWNLOAD_DIRECT, - Arrays.asList(result)); + DownloadUtils.batchDownload(context, result[0].getProfileModel().getUsername(), DownloadMethod.DOWNLOAD_DIRECT, + Arrays.asList(result)); } else if (result.length > 1) { context.startActivity(new Intent(context, MultiDirectDialog.class) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) diff --git a/app/src/main/java/awais/instagrabber/directdownload/MultiDirectDialog.java b/app/src/main/java/awais/instagrabber/directdownload/MultiDirectDialog.java index 159d477b..72553a9c 100755 --- a/app/src/main/java/awais/instagrabber/directdownload/MultiDirectDialog.java +++ b/app/src/main/java/awais/instagrabber/directdownload/MultiDirectDialog.java @@ -11,7 +11,6 @@ import androidx.appcompat.widget.Toolbar; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; -import java.util.Collections; import awais.instagrabber.R; import awais.instagrabber.activities.BaseLanguageActivity; @@ -23,6 +22,7 @@ import awais.instagrabber.models.PostModel; import awais.instagrabber.models.ViewerPostModel; import awais.instagrabber.models.enums.DownloadMethod; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.DownloadUtils; import awais.instagrabber.utils.Utils; public final class MultiDirectDialog extends BaseLanguageActivity { @@ -86,7 +86,7 @@ public final class MultiDirectDialog extends BaseLanguageActivity { @Override public boolean onOptionsItemSelected(@NonNull final MenuItem item) { - Utils.batchDownload(this, username, DownloadMethod.DOWNLOAD_DIRECT, selectedItems); + DownloadUtils.batchDownload(this, username, DownloadMethod.DOWNLOAD_DIRECT, selectedItems); finish(); return true; } diff --git a/app/src/main/java/awais/instagrabber/fragments/CommentsViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/CommentsViewerFragment.java index cba8a89c..5738236e 100644 --- a/app/src/main/java/awais/instagrabber/fragments/CommentsViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/CommentsViewerFragment.java @@ -44,6 +44,8 @@ import awais.instagrabber.models.ProfileModel; import awais.instagrabber.services.MediaService; import awais.instagrabber.services.ServiceCallback; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import static android.content.Context.INPUT_METHOD_SERVICE; @@ -134,7 +136,7 @@ public final class CommentsViewerFragment extends Fragment implements SwipeRefre binding.swipeRefreshLayout.setOnRefreshListener(this); binding.swipeRefreshLayout.setRefreshing(true); resources = getResources(); - if (!Utils.isEmpty(cookie)) { + if (!TextUtils.isEmpty(cookie)) { binding.commentField.setStartIconVisible(false); binding.commentField.setEndIconVisible(false); binding.commentField.setVisibility(View.VISIBLE); @@ -219,7 +221,7 @@ public final class CommentsViewerFragment extends Fragment implements SwipeRefre break; case 5: // like/unlike comment if (!commentModel.getLiked()) { - mediaService.commentLike(commentModel.getId(), Utils.getCsrfTokenFromCookie(cookie), new ServiceCallback() { + mediaService.commentLike(commentModel.getId(), CookieUtils.getCsrfTokenFromCookie(cookie), new ServiceCallback() { @Override public void onSuccess(final Boolean result) { commentModel = null; @@ -238,7 +240,7 @@ public final class CommentsViewerFragment extends Fragment implements SwipeRefre }); return; } - mediaService.commentUnlike(commentModel.getId(), Utils.getCsrfTokenFromCookie(cookie), new ServiceCallback() { + mediaService.commentUnlike(commentModel.getId(), CookieUtils.getCsrfTokenFromCookie(cookie), new ServiceCallback() { @Override public void onSuccess(final Boolean result) { commentModel = null; @@ -257,10 +259,10 @@ public final class CommentsViewerFragment extends Fragment implements SwipeRefre }); break; case 6: // delete comment - final String userId = Utils.getUserIdFromCookie(cookie); + final String userId = CookieUtils.getUserIdFromCookie(cookie); if (userId == null) return; mediaService.deleteComment( - postId, userId, commentModel.getId(), Utils.getCsrfTokenFromCookie(cookie), + postId, userId, commentModel.getId(), CookieUtils.getCsrfTokenFromCookie(cookie), new ServiceCallback() { @Override public void onSuccess(final Boolean result) { @@ -293,8 +295,8 @@ public final class CommentsViewerFragment extends Fragment implements SwipeRefre String[] commentDialogList; - final String userIdFromCookie = Utils.getUserIdFromCookie(cookie); - if (!Utils.isEmpty(cookie) + final String userIdFromCookie = CookieUtils.getUserIdFromCookie(cookie); + if (!TextUtils.isEmpty(cookie) && userIdFromCookie != null && (userIdFromCookie.equals(commentModel.getProfileModel().getId()) || userIdFromCookie.equals(userId))) { commentDialogList = new String[]{ @@ -307,7 +309,7 @@ public final class CommentsViewerFragment extends Fragment implements SwipeRefre : resources.getString(R.string.comment_viewer_like_comment), resources.getString(R.string.comment_viewer_delete_comment) }; - } else if (!Utils.isEmpty(cookie)) { + } else if (!TextUtils.isEmpty(cookie)) { commentDialogList = new String[]{ resources.getString(R.string.open_profile), resources.getString(R.string.view_pfp), @@ -344,17 +346,17 @@ public final class CommentsViewerFragment extends Fragment implements SwipeRefre private final View.OnClickListener newCommentListener = v -> { final Editable text = binding.commentText.getText(); - if (text == null || Utils.isEmpty(text.toString())) { + if (text == null || TextUtils.isEmpty(text.toString())) { Toast.makeText(requireContext(), R.string.comment_send_empty_comment, Toast.LENGTH_SHORT).show(); return; } - final String userId = Utils.getUserIdFromCookie(cookie); + final String userId = CookieUtils.getUserIdFromCookie(cookie); if (userId == null) return; String replyToId = null; if (commentModel != null) { replyToId = commentModel.getId(); } - mediaService.comment(postId, text.toString(), userId, replyToId, Utils.getCsrfTokenFromCookie(cookie), new ServiceCallback() { + mediaService.comment(postId, text.toString(), userId, replyToId, CookieUtils.getCsrfTokenFromCookie(cookie), new ServiceCallback() { @Override public void onSuccess(final Boolean result) { commentModel = null; diff --git a/app/src/main/java/awais/instagrabber/fragments/FollowViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/FollowViewerFragment.java index 754dfbc8..a440c26c 100644 --- a/app/src/main/java/awais/instagrabber/fragments/FollowViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/FollowViewerFragment.java @@ -30,7 +30,7 @@ import awais.instagrabber.asyncs.FollowFetcher; import awais.instagrabber.databinding.FragmentFollowersViewerBinding; import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.FollowModel; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.TextUtils; import awaisomereport.LogCollector; import thoughtbot.expandableadapter.ExpandableGroup; @@ -89,7 +89,7 @@ public final class FollowViewerFragment extends Fragment implements SwipeRefresh isFollowersList = fragmentArgs.getIsFollowersList(); username = fragmentArgs.getUsername(); namePost = username; - if (Utils.isEmpty(username)) { + if (TextUtils.isEmpty(username)) { // this usually should not occur username = "You"; namePost = "You're"; diff --git a/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java b/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java index c3428d31..0671e5f4 100644 --- a/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java @@ -1,6 +1,5 @@ package awais.instagrabber.fragments; -import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Typeface; import android.os.AsyncTask; @@ -53,6 +52,9 @@ import awais.instagrabber.models.StoryModel; import awais.instagrabber.models.enums.DownloadMethod; import awais.instagrabber.models.enums.PostItemType; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; +import awais.instagrabber.utils.DownloadUtils; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import awais.instagrabber.viewmodels.PostsViewModel; import awaisomereport.LogCollector; @@ -101,10 +103,10 @@ public class HashTagFragment extends Fragment { if (postsAdapter == null || hashtag == null) { return false; } - Utils.batchDownload(requireContext(), - hashtag, - DownloadMethod.DOWNLOAD_MAIN, - postsAdapter.getSelectedModels()); + DownloadUtils.batchDownload(requireContext(), + hashtag, + DownloadMethod.DOWNLOAD_MAIN, + postsAdapter.getSelectedModels()); checkAndResetAction(); return true; } @@ -168,7 +170,7 @@ public class HashTagFragment extends Fragment { private void init() { if (getArguments() == null) return; final String cookie = settingsHelper.getString(Constants.COOKIE); - isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null; + isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) != null; final HashTagFragmentArgs fragmentArgs = HashTagFragmentArgs.fromBundle(getArguments()); hashtag = fragmentArgs.getHashtag(); setTitle(); @@ -251,7 +253,7 @@ public class HashTagFragment extends Fragment { stopCurrentExecutor(); binding.btnFollowTag.setVisibility(View.VISIBLE); binding.swipeRefreshLayout.setRefreshing(true); - if (Utils.isEmpty(hashtag)) return; + if (TextUtils.isEmpty(hashtag)) return; currentlyExecuting = new PostsFetcher(hashtag.substring(1), PostItemType.HASHTAG, endCursor, postsFetchListener) .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); if (isLoggedIn) { diff --git a/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java b/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java index 42657494..4f9265c4 100644 --- a/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java @@ -44,6 +44,9 @@ import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration; import awais.instagrabber.customviews.helpers.NestedCoordinatorLayout; import awais.instagrabber.customviews.helpers.RecyclerLazyLoader; import awais.instagrabber.databinding.FragmentLocationBinding; +import awais.instagrabber.utils.CookieUtils; +import awais.instagrabber.utils.DownloadUtils; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.viewmodels.PostsViewModel; import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.LocationModel; @@ -103,10 +106,10 @@ public class LocationFragment extends Fragment { if (postsAdapter == null || locationId == null) { return false; } - Utils.batchDownload(requireContext(), - locationId, - DownloadMethod.DOWNLOAD_MAIN, - postsAdapter.getSelectedModels()); + DownloadUtils.batchDownload(requireContext(), + locationId, + DownloadMethod.DOWNLOAD_MAIN, + postsAdapter.getSelectedModels()); checkAndResetAction(); return true; } @@ -173,7 +176,7 @@ public class LocationFragment extends Fragment { private void init() { if (getArguments() == null) return; final String cookie = settingsHelper.getString(Constants.COOKIE); - isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null; + isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) != null; final LocationFragmentArgs fragmentArgs = LocationFragmentArgs.fromBundle(getArguments()); locationId = fragmentArgs.getLocationId(); setTitle(); @@ -284,11 +287,11 @@ public class LocationFragment extends Fragment { binding.locationBiography.setCaptionIsExpandable(true); binding.locationBiography.setCaptionIsExpanded(true); - if (Utils.isEmpty(biography)) { + if (TextUtils.isEmpty(biography)) { binding.locationBiography.setVisibility(View.GONE); - } else if (Utils.hasMentions(biography)) { + } else if (TextUtils.hasMentions(biography)) { binding.locationBiography.setVisibility(View.VISIBLE); - biography = Utils.getMentionText(biography); + biography = TextUtils.getMentionText(biography); binding.locationBiography.setText(biography, TextView.BufferType.SPANNABLE); // binding.locationBiography.setMentionClickListener(mentionClickListener); } else { @@ -310,14 +313,14 @@ public class LocationFragment extends Fragment { } final String url = locationModel.getUrl(); - if (Utils.isEmpty(url)) { + if (TextUtils.isEmpty(url)) { binding.locationUrl.setVisibility(View.GONE); } else if (!url.startsWith("http")) { binding.locationUrl.setVisibility(View.VISIBLE); - binding.locationUrl.setText(Utils.getSpannableUrl("http://" + url)); + binding.locationUrl.setText(TextUtils.getSpannableUrl("http://" + url)); } else { binding.locationUrl.setVisibility(View.VISIBLE); - binding.locationUrl.setText(Utils.getSpannableUrl(url)); + binding.locationUrl.setText(TextUtils.getSpannableUrl(url)); } } diff --git a/app/src/main/java/awais/instagrabber/fragments/PostViewFragment.java b/app/src/main/java/awais/instagrabber/fragments/PostViewFragment.java index 73abbd80..f68df3b0 100644 --- a/app/src/main/java/awais/instagrabber/fragments/PostViewFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/PostViewFragment.java @@ -38,6 +38,8 @@ import awais.instagrabber.models.enums.DownloadMethod; import awais.instagrabber.services.MediaService; import awais.instagrabber.services.ServiceCallback; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; +import awais.instagrabber.utils.DownloadUtils; import awais.instagrabber.utils.Utils; import awais.instagrabber.viewmodels.ViewerPostViewModel; @@ -129,13 +131,13 @@ public class PostViewFragment extends Fragment { break; case R.id.btnDownload: if (checkSelfPermission(requireContext(), - Utils.PERMS[0]) == PackageManager.PERMISSION_GRANTED) { + DownloadUtils.PERMS[0]) == PackageManager.PERMISSION_GRANTED) { showDownloadDialog(Arrays.asList(wrapper.getViewerPostModels()), childPosition, username); return; } - requestPermissions(Utils.PERMS, 8020); + requestPermissions(DownloadUtils.PERMS, 8020); break; case R.id.ivProfilePic: case R.id.title: @@ -143,8 +145,8 @@ public class PostViewFragment extends Fragment { break; case R.id.btnLike: if (mediaService != null) { - final String userId = Utils.getUserIdFromCookie(COOKIE); - final String csrfToken = Utils.getCsrfTokenFromCookie(COOKIE); + final String userId = CookieUtils.getUserIdFromCookie(COOKIE); + final String csrfToken = CookieUtils.getCsrfTokenFromCookie(COOKIE); v.setEnabled(false); final ServiceCallback likeCallback = new ServiceCallback() { @Override @@ -173,8 +175,8 @@ public class PostViewFragment extends Fragment { break; case R.id.btnBookmark: if (mediaService != null) { - final String userId = Utils.getUserIdFromCookie(COOKIE); - final String csrfToken = Utils.getCsrfTokenFromCookie(COOKIE); + final String userId = CookieUtils.getUserIdFromCookie(COOKIE); + final String csrfToken = CookieUtils.getCsrfTokenFromCookie(COOKIE); v.setEnabled(false); final ServiceCallback saveCallback = new ServiceCallback() { @Override @@ -312,10 +314,10 @@ public class PostViewFragment extends Fragment { postModelsToDownload.add(postModels.get(childPosition)); } if (postModelsToDownload.size() > 0) { - Utils.batchDownload(requireContext(), - username, - DownloadMethod.DOWNLOAD_POST_VIEWER, - postModelsToDownload); + DownloadUtils.batchDownload(requireContext(), + username, + DownloadMethod.DOWNLOAD_POST_VIEWER, + postModelsToDownload); } }; new AlertDialog.Builder(requireContext()) @@ -325,10 +327,10 @@ public class PostViewFragment extends Fragment { .setPositiveButton(R.string.post_viewer_download_current, clickListener) .setNegativeButton(R.string.post_viewer_download_album, clickListener).show(); } else { - Utils.batchDownload(requireContext(), - username, - DownloadMethod.DOWNLOAD_POST_VIEWER, - Collections.singletonList(postModels.get(childPosition))); + DownloadUtils.batchDownload(requireContext(), + username, + DownloadMethod.DOWNLOAD_POST_VIEWER, + Collections.singletonList(postModels.get(childPosition))); } } } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/fragments/SavedViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/SavedViewerFragment.java index 68dde31e..e076ef37 100644 --- a/app/src/main/java/awais/instagrabber/fragments/SavedViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/SavedViewerFragment.java @@ -41,6 +41,8 @@ import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration; import awais.instagrabber.customviews.helpers.RecyclerLazyLoader; import awais.instagrabber.databinding.FragmentSavedBinding; import awais.instagrabber.fragments.main.ProfileFragmentDirections; +import awais.instagrabber.utils.DownloadUtils; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.viewmodels.PostsViewModel; import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.PostModel; @@ -92,10 +94,10 @@ public final class SavedViewerFragment extends Fragment implements SwipeRefreshL if (postsAdapter == null || username == null) { return false; } - Utils.batchDownload(requireContext(), - username, - DownloadMethod.DOWNLOAD_SAVED, - postsAdapter.getSelectedModels()); + DownloadUtils.batchDownload(requireContext(), + username, + DownloadMethod.DOWNLOAD_SAVED, + postsAdapter.getSelectedModels()); checkAndResetAction(); return true; } @@ -257,7 +259,7 @@ public final class SavedViewerFragment extends Fragment implements SwipeRefreshL break; case SAVED: case TAGGED: - if (Utils.isEmpty(profileId)) return; + if (TextUtils.isEmpty(profileId)) return; asyncTask = new PostsFetcher(profileId, type, endCursor, postsFetchListener); break; default: @@ -285,7 +287,7 @@ public final class SavedViewerFragment extends Fragment implements SwipeRefreshL public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 8020 && grantResults[0] == PackageManager.PERMISSION_GRANTED && selectedItems.size() > 0) - Utils.batchDownload(requireContext(), null, DownloadMethod.DOWNLOAD_SAVED, selectedItems); + DownloadUtils.batchDownload(requireContext(), null, DownloadMethod.DOWNLOAD_SAVED, selectedItems); } public static void stopCurrentExecutor() { diff --git a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java index fa084e94..d3d78cb0 100644 --- a/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/StoryViewerFragment.java @@ -81,6 +81,9 @@ import awais.instagrabber.models.stickers.QuizModel; import awais.instagrabber.services.ServiceCallback; import awais.instagrabber.services.StoriesService; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; +import awais.instagrabber.utils.DownloadUtils; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import awais.instagrabber.viewmodels.FeedStoriesViewModel; import awais.instagrabber.viewmodels.HighlightsViewModel; @@ -175,10 +178,10 @@ public class StoryViewerFragment extends Fragment { public boolean onOptionsItemSelected(@NonNull final MenuItem item) { switch (item.getItemId()) { case R.id.action_download: - if (ContextCompat.checkSelfPermission(requireContext(), Utils.PERMS[0]) == PackageManager.PERMISSION_GRANTED) + if (ContextCompat.checkSelfPermission(requireContext(), DownloadUtils.PERMS[0]) == PackageManager.PERMISSION_GRANTED) downloadStory(); else - ActivityCompat.requestPermissions(requireActivity(), Utils.PERMS, 8020); + ActivityCompat.requestPermissions(requireActivity(), DownloadUtils.PERMS, 8020); return true; case R.id.action_dms: final EditText input = new EditText(requireContext()); @@ -236,12 +239,12 @@ public class StoryViewerFragment extends Fragment { } private void init() { - isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null; + isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) != null; if (getArguments() == null) return; fragmentArgs = StoryViewerFragmentArgs.fromBundle(getArguments()); currentFeedStoryIndex = fragmentArgs.getFeedStoryIndex(); highlight = fragmentArgs.getHighlight(); - isHighlight = !Utils.isEmpty(highlight); + isHighlight = !TextUtils.isEmpty(highlight); if (currentFeedStoryIndex >= 0) { viewModel = isHighlight ? new ViewModelProvider(fragmentActivity).get(HighlightsViewModel.class) @@ -394,7 +397,7 @@ public class StoryViewerFragment extends Fragment { poll.getLeftChoice() + " (" + poll.getLeftCount() + ")", poll.getRightChoice() + " (" + poll.getRightCount() + ")" }), (d, w) -> { - if (!Utils.isEmpty(cookie)) + if (!TextUtils.isEmpty(cookie)) new VoteAction(currentStory, poll, cookie, choice -> { if (choice > -1) { poll.setMyChoice(choice); @@ -439,7 +442,7 @@ public class StoryViewerFragment extends Fragment { new AlertDialog.Builder(requireContext()) .setTitle(quiz.getMyChoice() > -1 ? getString(R.string.story_quizzed) : quiz.getQuestion()) .setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1, choices), (d, w) -> { - if (quiz.getMyChoice() == -1 && !Utils.isEmpty(cookie)) + if (quiz.getMyChoice() == -1 && !TextUtils.isEmpty(cookie)) new QuizAction(currentStory, quiz, cookie, choice -> { if (choice > -1) { quiz.setMyChoice(choice); @@ -484,12 +487,12 @@ public class StoryViewerFragment extends Fragment { currentStoryMediaId = model.getStoryMediaId(); currentStoryUsername = model.getProfileModel().getUsername(); } - } else if (!Utils.isEmpty(fragmentArgs.getProfileId()) && !Utils.isEmpty(fragmentArgs.getUsername())) { + } else if (!TextUtils.isEmpty(fragmentArgs.getProfileId()) && !TextUtils.isEmpty(fragmentArgs.getUsername())) { currentStoryMediaId = fragmentArgs.getProfileId(); username = fragmentArgs.getUsername(); } isHashtag = fragmentArgs.getIsHashtag(); - final boolean hasUsername = !Utils.isEmpty(currentStoryUsername); + final boolean hasUsername = !TextUtils.isEmpty(currentStoryUsername); if (hasUsername) { currentStoryUsername = currentStoryUsername.replace("@", ""); final ActionBar actionBar = fragmentActivity.getSupportActionBar(); @@ -572,7 +575,7 @@ public class StoryViewerFragment extends Fragment { binding.poll.setTag(poll); question = currentStory.getQuestion(); - binding.answer.setVisibility((question != null && !Utils.isEmpty(cookie)) ? View.VISIBLE : View.GONE); + binding.answer.setVisibility((question != null && !TextUtils.isEmpty(cookie)) ? View.VISIBLE : View.GONE); binding.answer.setTag(question); mentions = currentStory.getMentions(); @@ -611,10 +614,10 @@ public class StoryViewerFragment extends Fragment { if (settingsHelper.getBoolean(FOLDER_SAVE_TO)) { final String customPath = settingsHelper.getString(FOLDER_PATH); - if (!Utils.isEmpty(customPath)) dir = new File(customPath); + if (!TextUtils.isEmpty(customPath)) dir = new File(customPath); } - if (settingsHelper.getBoolean(Constants.DOWNLOAD_USER_FOLDER) && !Utils.isEmpty(currentStoryUsername)) + if (settingsHelper.getBoolean(Constants.DOWNLOAD_USER_FOLDER) && !TextUtils.isEmpty(currentStoryUsername)) dir = new File(dir, currentStoryUsername); if (dir.exists() || dir.mkdirs()) { @@ -622,7 +625,7 @@ public class StoryViewerFragment extends Fragment { ? currentStory.getVideoUrl() : currentStory.getStoryUrl(); final File saveFile = new File(dir, currentStory.getStoryMediaId() + "_" + currentStory.getTimestamp() - + Utils.getExtensionFromModel(storyUrl, currentStory)); + + DownloadUtils.getExtensionFromModel(storyUrl, currentStory)); new DownloadAsync(requireContext(), storyUrl, saveFile, result -> { final int toastRes = result != null && result.exists() ? R.string.downloader_complete @@ -664,7 +667,7 @@ public class StoryViewerFragment extends Fragment { if (menuDownload != null) { menuDownload.setVisible(true); } - if (currentStory.canReply() && menuDm != null && !Utils.isEmpty(cookie)) { + if (currentStory.canReply() && menuDm != null && !TextUtils.isEmpty(cookie)) { menuDm.setVisible(true); } binding.progressView.setVisibility(View.GONE); @@ -693,7 +696,7 @@ public class StoryViewerFragment extends Fragment { final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) { if (menuDownload != null) menuDownload.setVisible(true); - if (currentStory.canReply() && menuDm != null && !Utils.isEmpty(cookie)) + if (currentStory.canReply() && menuDm != null && !TextUtils.isEmpty(cookie)) menuDm.setVisible(true); binding.progressView.setVisibility(View.GONE); } @@ -704,7 +707,7 @@ public class StoryViewerFragment extends Fragment { final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) { if (menuDownload != null) menuDownload.setVisible(true); - if (currentStory.canReply() && menuDm != null && !Utils.isEmpty(cookie)) + if (currentStory.canReply() && menuDm != null && !TextUtils.isEmpty(cookie)) menuDm.setVisible(true); binding.progressView.setVisibility(View.VISIBLE); } diff --git a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageInboxFragment.java b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageInboxFragment.java index 0a7e97fa..38c91a31 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageInboxFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageInboxFragment.java @@ -34,7 +34,7 @@ import awais.instagrabber.databinding.FragmentDirectMessagesInboxBinding; import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.direct_messages.InboxModel; import awais.instagrabber.models.direct_messages.InboxThreadModel; -import awais.instagrabber.utils.Utils; +import awais.instagrabber.utils.TextUtils; public class DirectMessageInboxFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener { private static final String TAG = "DirectMessagesInboxFrag"; @@ -145,7 +145,7 @@ public class DirectMessageInboxFragment extends Fragment implements SwipeRefresh private void initData() { lazyLoader = new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> { - if (!Utils.isEmpty(endCursor)) + if (!TextUtils.isEmpty(endCursor)) currentlyRunning = new InboxFetcher(endCursor, fetchListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); endCursor = null; }); diff --git a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java index f065cb06..8fc25ff0 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageSettingsFragment.java @@ -42,6 +42,7 @@ import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.ProfileModel; import awais.instagrabber.models.direct_messages.InboxThreadModel; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.Utils; public class DirectMessageSettingsFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener { @@ -66,7 +67,7 @@ public class DirectMessageSettingsFragment extends Fragment implements SwipeRefr @Override public void onResult(final InboxThreadModel threadModel) { final List adminList = Arrays.asList(threadModel.getAdmins()); - final String userIdFromCookie = Utils.getUserIdFromCookie(cookie); + final String userIdFromCookie = CookieUtils.getUserIdFromCookie(cookie); if (userIdFromCookie == null) return; final boolean amAdmin = adminList.contains(Long.parseLong(userIdFromCookie)); final DirectMessageMembersAdapter memberAdapter = new DirectMessageMembersAdapter(threadModel.getUsers(), diff --git a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java index 76037798..a7384f2b 100644 --- a/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/directmessages/DirectMessageThreadFragment.java @@ -68,6 +68,9 @@ import awais.instagrabber.models.enums.DownloadMethod; import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.models.enums.UserInboxDirection; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; +import awais.instagrabber.utils.DownloadUtils; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; public class DirectMessageThreadFragment extends Fragment { @@ -80,7 +83,7 @@ public class DirectMessageThreadFragment extends Fragment { private String cursor; private String lastMessage; private final String cookie = Utils.settingsHelper.getString(Constants.COOKIE); - private final String myId = Utils.getUserIdFromCookie(cookie); + private final String myId = CookieUtils.getUserIdFromCookie(cookie); private FragmentDirectMessagesThreadBinding binding; private DirectItemModelListViewModel listViewModel; private DirectItemModel directItemModel; @@ -97,7 +100,7 @@ public class DirectMessageThreadFragment extends Fragment { private final View.OnClickListener clickListener = v -> { if (v == binding.commentSend) { final String text = binding.commentText.getText().toString(); - if (Utils.isEmpty(text)) { + if (TextUtils.isEmpty(text)) { Toast.makeText(requireContext(), R.string.comment_send_empty_comment, Toast.LENGTH_SHORT).show(); return; } @@ -120,7 +123,7 @@ public class DirectMessageThreadFragment extends Fragment { @Override public void onResult(final InboxThreadModel result) { - if (result == null && ("MINCURSOR".equals(cursor) || "MAXCURSOR".equals(cursor) || Utils.isEmpty(cursor))) + if (result == null && ("MINCURSOR".equals(cursor) || "MAXCURSOR".equals(cursor) || TextUtils.isEmpty(cursor))) Toast.makeText(requireContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); if (result != null) { @@ -210,7 +213,7 @@ public class DirectMessageThreadFragment extends Fragment { layoutManager.setReverseLayout(true); messageList.setLayoutManager(layoutManager); messageList.addOnScrollListener(new RecyclerLazyLoader(layoutManager, (page, totalItemsCount) -> { - if (Utils.isEmpty(cursor) || !hasOlder) { + if (TextUtils.isEmpty(cursor) || !hasOlder) { return; } new DirectMessageInboxThreadFetcher(threadId, UserInboxDirection.OLDER, cursor, fetchListener) @@ -255,7 +258,7 @@ public class DirectMessageThreadFragment extends Fragment { if (url == null) { Toast.makeText(requireContext(), R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); } else { - Utils.dmDownload(requireContext(), user.getUsername(), DownloadMethod.DOWNLOAD_DIRECT, selectedItem); + DownloadUtils.dmDownload(requireContext(), user.getUsername(), DownloadMethod.DOWNLOAD_DIRECT, selectedItem); Toast.makeText(requireContext(), R.string.downloader_downloading_media, Toast.LENGTH_SHORT).show(); } break; diff --git a/app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java index 89566f60..d9795045 100644 --- a/app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/main/DiscoverFragment.java @@ -36,6 +36,7 @@ import awais.instagrabber.customviews.helpers.GridAutofitLayoutManager; import awais.instagrabber.customviews.helpers.GridSpacingItemDecoration; import awais.instagrabber.customviews.helpers.RecyclerLazyLoader; import awais.instagrabber.databinding.FragmentDiscoverBinding; +import awais.instagrabber.utils.DownloadUtils; import awais.instagrabber.viewmodels.DiscoverItemViewModel; import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.DiscoverItemModel; @@ -129,10 +130,10 @@ public class DiscoverFragment extends Fragment implements SwipeRefreshLayout.OnR public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) { if (item.getItemId() == R.id.action_download) { if (discoverAdapter == null) return false; - Utils.batchDownload(requireContext(), - null, - DownloadMethod.DOWNLOAD_DISCOVER, - discoverAdapter.getSelectedModels()); + DownloadUtils.batchDownload(requireContext(), + null, + DownloadMethod.DOWNLOAD_DISCOVER, + discoverAdapter.getSelectedModels()); checkAndResetAction(); return true; } diff --git a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java index a0f01ee3..300c84cc 100644 --- a/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/main/FeedFragment.java @@ -57,6 +57,8 @@ import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.services.ServiceCallback; import awais.instagrabber.services.StoriesService; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.DownloadUtils; +import awais.instagrabber.utils.NumberUtils; import awais.instagrabber.utils.Utils; import awais.instagrabber.viewmodels.FeedStoriesViewModel; import awais.instagrabber.viewmodels.FeedViewModel; @@ -113,16 +115,16 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre final FeedModel feedModel = thumbToFeedMap.get(thumbUri.toString()); if (feedModel == null) return; int requiredWidth = Utils.displayMetrics.widthPixels; - int resultingHeight = Utils + int resultingHeight = NumberUtils .getResultingHeight(requiredWidth, encodedHeight, encodedWidth); if (feedModel .getItemType() == MediaItemType.MEDIA_TYPE_VIDEO && resultingHeight >= MAX_VIDEO_HEIGHT) { // If its a video and the height is too large, need to reduce the height, // so that entire video fits on screen resultingHeight = RESIZED_VIDEO_HEIGHT; - requiredWidth = Utils.getResultingWidth(RESIZED_VIDEO_HEIGHT, - resultingHeight, - requiredWidth); + requiredWidth = NumberUtils.getResultingWidth(RESIZED_VIDEO_HEIGHT, + resultingHeight, + requiredWidth); } feedModel.setImageWidth(requiredWidth); feedModel.setImageHeight(resultingHeight); @@ -229,10 +231,10 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre if (feedModel .getItemType() != MediaItemType.MEDIA_TYPE_SLIDER || sliderItems == null || sliderItems.length == 1) - Utils.batchDownload(requireContext(), - username, - DownloadMethod.DOWNLOAD_FEED, - Collections.singletonList(feedModel)); + DownloadUtils.batchDownload(requireContext(), + username, + DownloadMethod.DOWNLOAD_FEED, + Collections.singletonList(feedModel)); else { final ArrayList postModels = new ArrayList<>(); final DialogInterface.OnClickListener clickListener1 = (dialog, which) -> { @@ -255,10 +257,10 @@ public class FeedFragment extends Fragment implements SwipeRefreshLayout.OnRefre postModels.add(sliderItems[0]); } if (postModels.size() > 0) { - Utils.batchDownload(requireContext(), - username, - DownloadMethod.DOWNLOAD_FEED, - postModels); + DownloadUtils.batchDownload(requireContext(), + username, + DownloadMethod.DOWNLOAD_FEED, + postModels); } }; diff --git a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java index 4d6de2c0..2f4c14be 100644 --- a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java @@ -76,7 +76,10 @@ import awais.instagrabber.repositories.responses.FriendshipRepoRestrictRootRespo import awais.instagrabber.services.FriendshipService; import awais.instagrabber.services.ServiceCallback; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.DataBox; +import awais.instagrabber.utils.DownloadUtils; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import awais.instagrabber.viewmodels.HighlightsViewModel; import awais.instagrabber.viewmodels.PostsViewModel; @@ -112,7 +115,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe private final Runnable usernameSettingRunnable = () -> { final ActionBar actionBar = fragmentActivity.getSupportActionBar(); - if (actionBar != null && !Utils.isEmpty(username)) { + if (actionBar != null && !TextUtils.isEmpty(username)) { final String finalUsername = username.startsWith("@") ? username.substring(1) : username; actionBar.setTitle(finalUsername); @@ -142,10 +145,10 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe if (postsAdapter == null || username == null) { return false; } - Utils.batchDownload(requireContext(), - username, - DownloadMethod.DOWNLOAD_MAIN, - postsAdapter.getSelectedModels()); + DownloadUtils.batchDownload(requireContext(), + username, + DownloadMethod.DOWNLOAD_MAIN, + postsAdapter.getSelectedModels()); checkAndResetAction(); return true; } @@ -213,12 +216,12 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe final ViewGroup container, final Bundle savedInstanceState) { cookie = settingsHelper.getString(Constants.COOKIE); - isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null; + isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) != null; if (root != null) { if (getArguments() != null) { final ProfileFragmentArgs fragmentArgs = ProfileFragmentArgs.fromBundle(getArguments()); final String username = fragmentArgs.getUsername(); - if (Utils.isEmpty(username) && profileModel != null) { + if (TextUtils.isEmpty(username) && profileModel != null) { final String profileModelUsername = profileModel.getUsername(); final boolean isSame = ("@" + profileModelUsername).equals(this.username); if (isSame) { @@ -283,7 +286,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe username = fragmentArgs.getUsername(); setUsernameDelayed(); } - if (Utils.isEmpty(username) && !isLoggedIn) { + if (TextUtils.isEmpty(username) && !isLoggedIn) { binding.infoContainer.setVisibility(View.GONE); binding.privatePage1.setImageResource(R.drawable.ic_outline_info_24); binding.privatePage2.setText(R.string.no_acc); @@ -300,10 +303,10 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe } private void fetchUsername() { - final String uid = Utils.getUserIdFromCookie(cookie); - if (Utils.isEmpty(username) && uid != null) { + final String uid = CookieUtils.getUserIdFromCookie(cookie); + if (TextUtils.isEmpty(username) && uid != null) { final FetchListener fetchListener = username -> { - if (Utils.isEmpty(username)) return; + if (TextUtils.isEmpty(username)) return; this.username = username; setUsernameDelayed(); fetchProfileDetails(); @@ -312,7 +315,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe final DataBox.CookieModel cookieModel = Utils.dataBox.getCookie(uid); if (cookieModel != null) { final String username = cookieModel.getUsername(); - if (!Utils.isEmpty(username)) { + if (!TextUtils.isEmpty(username)) { found = true; fetchListener.onResult("@" + username); } @@ -330,7 +333,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe new ProfileFetcher(username.substring(1), profileModel -> { if (getContext() == null) return; this.profileModel = profileModel; - final String userIdFromCookie = Utils.getUserIdFromCookie(cookie); + final String userIdFromCookie = CookieUtils.getUserIdFromCookie(cookie); final boolean isSelf = isLoggedIn && profileModel != null && userIdFromCookie != null @@ -375,7 +378,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe } if (isLoggedIn) { - final String myId = Utils.getUserIdFromCookie(cookie); + final String myId = CookieUtils.getUserIdFromCookie(cookie); if (profileId.equals(myId)) { binding.btnTagged.setVisibility(View.VISIBLE); binding.btnSaved.setVisibility(View.VISIBLE); @@ -471,14 +474,14 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe span.setSpan(new StyleSpan(Typeface.BOLD), 0, followingCountStrLen, 0); binding.mainFollowing.setText(span); - binding.mainFullName.setText(Utils.isEmpty(profileModel.getName()) ? profileModel.getUsername() - : profileModel.getName()); + binding.mainFullName.setText(TextUtils.isEmpty(profileModel.getName()) ? profileModel.getUsername() + : profileModel.getName()); CharSequence biography = profileModel.getBiography(); binding.mainBiography.setCaptionIsExpandable(true); binding.mainBiography.setCaptionIsExpanded(true); - if (Utils.hasMentions(biography)) { - biography = Utils.getMentionText(biography); + if (TextUtils.hasMentions(biography)) { + biography = TextUtils.getMentionText(biography); binding.mainBiography.setText(biography, TextView.BufferType.SPANNABLE); binding.mainBiography.setMentionClickListener(mentionClickListener); } else { @@ -487,11 +490,11 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe } final String url = profileModel.getUrl(); - if (Utils.isEmpty(url)) { + if (TextUtils.isEmpty(url)) { binding.mainUrl.setVisibility(View.GONE); } else { binding.mainUrl.setVisibility(View.VISIBLE); - binding.mainUrl.setText(Utils.getSpannableUrl(url)); + binding.mainUrl.setText(TextUtils.getSpannableUrl(url)); binding.mainUrl.setMovementMethod(LinkMovementMethod.getInstance()); } @@ -539,7 +542,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe private void setupCommonListeners() { - final String userIdFromCookie = Utils.getUserIdFromCookie(cookie); + final String userIdFromCookie = CookieUtils.getUserIdFromCookie(cookie); // final boolean isSelf = isLoggedIn && profileModel != null && userIdFromCookie != null && userIdFromCookie // .equals(profileModel.getId()); final String favorite = Utils.dataBox.getFavorite(username); @@ -563,7 +566,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe friendshipService.unfollow( userIdFromCookie, profileModel.getId(), - Utils.getCsrfTokenFromCookie(cookie), + CookieUtils.getCsrfTokenFromCookie(cookie), new ServiceCallback() { @Override public void onSuccess(final FriendshipRepoChangeRootResponse result) { @@ -580,7 +583,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe friendshipService.follow( userIdFromCookie, profileModel.getId(), - Utils.getCsrfTokenFromCookie(cookie), + CookieUtils.getCsrfTokenFromCookie(cookie), new ServiceCallback() { @Override public void onSuccess(final FriendshipRepoChangeRootResponse result) { @@ -601,7 +604,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe friendshipService.toggleRestrict( profileModel.getId(), !profileModel.getRestricted(), - Utils.getCsrfTokenFromCookie(cookie), + CookieUtils.getCsrfTokenFromCookie(cookie), new ServiceCallback() { @Override public void onSuccess(final FriendshipRepoRestrictRootResponse result) { @@ -621,7 +624,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe friendshipService.unblock( userIdFromCookie, profileModel.getId(), - Utils.getCsrfTokenFromCookie(cookie), + CookieUtils.getCsrfTokenFromCookie(cookie), new ServiceCallback() { @Override public void onSuccess(final FriendshipRepoChangeRootResponse result) { @@ -639,7 +642,7 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe friendshipService.block( userIdFromCookie, profileModel.getId(), - Utils.getCsrfTokenFromCookie(cookie), + CookieUtils.getCsrfTokenFromCookie(cookie), new ServiceCallback() { @Override public void onSuccess(final FriendshipRepoChangeRootResponse result) { diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/MorePreferencesFragment.java b/app/src/main/java/awais/instagrabber/fragments/settings/MorePreferencesFragment.java index 369ea7e9..3762f397 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/MorePreferencesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/settings/MorePreferencesFragment.java @@ -34,8 +34,10 @@ import awais.instagrabber.repositories.responses.UserInfo; import awais.instagrabber.services.ProfileService; import awais.instagrabber.services.ServiceCallback; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.DataBox; import awais.instagrabber.utils.FlavorTown; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import static awais.instagrabber.adapters.AccountSwitcherListAdapter.OnAccountLongClickListener; @@ -50,7 +52,7 @@ public class MorePreferencesFragment extends BasePreferencesFragment { @Override void setupPreferenceScreen(final PreferenceScreen screen) { final String cookie = settingsHelper.getString(Constants.COOKIE); - final boolean isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null; + final boolean isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) != null; // screen.addPreference(new MoreHeaderPreference(requireContext())); final PreferenceCategory accountCategory = new PreferenceCategory(requireContext()); @@ -76,7 +78,7 @@ public class MorePreferencesFragment extends BasePreferencesFragment { + "To remove just one account, long tap the account from the account switcher dialog.\n" + "Do you want to continue?") .setPositiveButton(R.string.yes, (dialog, which) -> { - Utils.setupCookies("LOGOUT"); + CookieUtils.setupCookies("LOGOUT"); shouldRecreate(); Toast.makeText(requireContext(), R.string.logout_success, Toast.LENGTH_SHORT).show(); settingsHelper.putString(Constants.COOKIE, ""); @@ -122,13 +124,13 @@ public class MorePreferencesFragment extends BasePreferencesFragment { if (resultCode == Constants.LOGIN_RESULT_CODE) { if (data == null) return; final String cookie = data.getStringExtra("cookie"); - Utils.setupCookies(cookie); + CookieUtils.setupCookies(cookie); settingsHelper.putString(Constants.COOKIE, cookie); // No use as the timing of show is unreliable // Toast.makeText(requireContext(), R.string.login_success_loading_cookies, Toast.LENGTH_SHORT).show(); // adds cookies to database for quick access - final String uid = Utils.getUserIdFromCookie(cookie); + final String uid = CookieUtils.getUserIdFromCookie(cookie); final ProfileService profileService = ProfileService.getInstance(); profileService.getUserInfo(uid, new ServiceCallback() { @Override @@ -204,7 +206,7 @@ public class MorePreferencesFragment extends BasePreferencesFragment { .create(); accountSwitchDialog.setOnDismissListener(dialog -> { if (tappedModel == null) return; - Utils.setupCookies(tappedModel.getCookie()); + CookieUtils.setupCookies(tappedModel.getCookie()); settingsHelper.putString(Constants.COOKIE, tappedModel.getCookie()); }); } @@ -230,7 +232,7 @@ public class MorePreferencesFragment extends BasePreferencesFragment { private void sortUserList(final String cookie, final List allUsers) { boolean sortByName = true; for (final DataBox.CookieModel user : allUsers) { - if (Utils.isEmpty(user.getFullName())) { + if (TextUtils.isEmpty(user.getFullName())) { sortByName = false; break; } @@ -280,7 +282,7 @@ public class MorePreferencesFragment extends BasePreferencesFragment { if (icon <= 0) preference.setIconSpaceReserved(false); if (icon > 0) preference.setIcon(icon); preference.setTitle(title); - if (!Utils.isEmpty(summary)) { + if (!TextUtils.isEmpty(summary)) { preference.setSummary(summary); } preference.setOnPreferenceClickListener(clickListener); @@ -316,7 +318,7 @@ public class MorePreferencesFragment extends BasePreferencesFragment { final View root = holder.itemView; if (onClickListener != null) root.setOnClickListener(onClickListener); final PrefAccountSwitcherBinding binding = PrefAccountSwitcherBinding.bind(root); - final String uid = Utils.getUserIdFromCookie(cookie); + final String uid = CookieUtils.getUserIdFromCookie(cookie); final DataBox.CookieModel user = Utils.dataBox.getCookie(uid); if (user == null) return; binding.fullName.setText(user.getFullName()); diff --git a/app/src/main/java/awais/instagrabber/fragments/settings/SettingsPreferencesFragment.java b/app/src/main/java/awais/instagrabber/fragments/settings/SettingsPreferencesFragment.java index 170e5834..abcaa3b8 100644 --- a/app/src/main/java/awais/instagrabber/fragments/settings/SettingsPreferencesFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/settings/SettingsPreferencesFragment.java @@ -2,11 +2,9 @@ package awais.instagrabber.fragments.settings; import android.content.Context; import android.content.res.TypedArray; -import android.os.Bundle; import android.view.View; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.appcompat.widget.AppCompatButton; import androidx.appcompat.widget.AppCompatTextView; import androidx.fragment.app.FragmentActivity; @@ -25,7 +23,9 @@ import java.util.Date; import awais.instagrabber.R; import awais.instagrabber.dialogs.TimeSettingsDialog; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.DirectoryChooser; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; import static awais.instagrabber.utils.Constants.FOLDER_PATH; @@ -40,7 +40,7 @@ public class SettingsPreferencesFragment extends BasePreferencesFragment { @Override void setupPreferenceScreen(final PreferenceScreen screen) { final String cookie = settingsHelper.getString(Constants.COOKIE); - isLoggedIn = !Utils.isEmpty(cookie) && Utils.getUserIdFromCookie(cookie) != null; + isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) != null; final PreferenceCategory generalCategory = new PreferenceCategory(requireContext()); screen.addPreference(generalCategory); generalCategory.setTitle(getString(R.string.pref_category_general)); @@ -331,7 +331,7 @@ public class SettingsPreferencesFragment extends BasePreferencesFragment { btnSaveTo.setOnClickListener(v -> { if (onSelectFolderButtonClickListener == null) return; onSelectFolderButtonClickListener.onClick(result -> { - if (Utils.isEmpty(result)) return; + if (TextUtils.isEmpty(result)) return; customPathTextView.setText(result); }); }); diff --git a/app/src/main/java/awais/instagrabber/models/CommentModel.java b/app/src/main/java/awais/instagrabber/models/CommentModel.java index 88d93461..733e1c92 100755 --- a/app/src/main/java/awais/instagrabber/models/CommentModel.java +++ b/app/src/main/java/awais/instagrabber/models/CommentModel.java @@ -4,6 +4,7 @@ import androidx.annotation.NonNull; import java.util.Date; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; public final class CommentModel { @@ -18,7 +19,7 @@ public final class CommentModel { public CommentModel(final String id, final String text, final long timestamp, final long likes, final boolean liked, final ProfileModel profileModel) { this.id = id; - this.text = Utils.hasMentions(text) ? Utils.getMentionText(text) : text; + this.text = TextUtils.hasMentions(text) ? TextUtils.getMentionText(text) : text; this.likes = likes; this.liked = liked; this.timestamp = timestamp; diff --git a/app/src/main/java/awais/instagrabber/models/NotificationModel.java b/app/src/main/java/awais/instagrabber/models/NotificationModel.java index 41686576..850d184a 100755 --- a/app/src/main/java/awais/instagrabber/models/NotificationModel.java +++ b/app/src/main/java/awais/instagrabber/models/NotificationModel.java @@ -5,6 +5,7 @@ import androidx.annotation.NonNull; import java.util.Date; import awais.instagrabber.models.enums.NotificationType; +import awais.instagrabber.utils.TextUtils; import awais.instagrabber.utils.Utils; public final class NotificationModel { @@ -16,7 +17,7 @@ public final class NotificationModel { public NotificationModel(final String id, final String text, final long timestamp, final String username, final String profilePicUrl, final String shortcode, final String previewUrl, final NotificationType type) { this.id = id; - this.text = Utils.hasMentions(text) ? Utils.getMentionText(text) : text; + this.text = TextUtils.hasMentions(text) ? TextUtils.getMentionText(text) : text; this.timestamp = timestamp; this.username = username; this.profilePicUrl = profilePicUrl; diff --git a/app/src/main/java/awais/instagrabber/models/direct_messages/DirectItemModel.java b/app/src/main/java/awais/instagrabber/models/direct_messages/DirectItemModel.java index d5a79c07..6f417c64 100755 --- a/app/src/main/java/awais/instagrabber/models/direct_messages/DirectItemModel.java +++ b/app/src/main/java/awais/instagrabber/models/direct_messages/DirectItemModel.java @@ -11,6 +11,7 @@ import awais.instagrabber.models.enums.DirectItemType; import awais.instagrabber.models.enums.MediaItemType; import awais.instagrabber.models.enums.RavenExpiringMediaType; import awais.instagrabber.models.enums.RavenMediaViewType; +import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.Utils; import static awais.instagrabber.utils.Constants.COOKIE; @@ -39,7 +40,7 @@ public final class DirectItemModel implements Serializable, Comparable map = new HashMap<>(); + + static { + for (NotificationType type : NotificationType.values()) { + map.put(type.itemType, type); + } + } + + NotificationType(final String itemType) { + this.itemType = itemType; + } + + public String getItemType() { + return itemType; + } + + public static NotificationType valueOfType(final String itemType) { + return map.get(itemType); + } } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/services/MediaService.java b/app/src/main/java/awais/instagrabber/services/MediaService.java index 125b99c6..aad0f997 100644 --- a/app/src/main/java/awais/instagrabber/services/MediaService.java +++ b/app/src/main/java/awais/instagrabber/services/MediaService.java @@ -128,7 +128,7 @@ public class MediaService extends BaseService { form.put("_uuid", UUID.randomUUID().toString()); form.put("comment_text", comment); form.put("containermodule", module); - if (!Utils.isEmpty(replyToCommentId)) { + if (!awais.instagrabber.utils.TextUtils.isEmpty(replyToCommentId)) { form.put("replied_to_comment_id", replyToCommentId); } final Map signedForm = Utils.sign(form); diff --git a/app/src/main/java/awais/instagrabber/services/StoriesService.java b/app/src/main/java/awais/instagrabber/services/StoriesService.java index adbd5005..0556af52 100644 --- a/app/src/main/java/awais/instagrabber/services/StoriesService.java +++ b/app/src/main/java/awais/instagrabber/services/StoriesService.java @@ -22,7 +22,7 @@ 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.Utils; +import awais.instagrabber.utils.ResponseBodyUtils; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -149,7 +149,7 @@ public class StoriesService extends BaseService { final JSONArray videoResources = data.optJSONArray("video_versions"); if (isVideo && videoResources != null) - model.setVideoUrl(Utils.getHighQualityPost(videoResources, true, true, false)); + 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")); diff --git a/app/src/main/java/awais/instagrabber/utils/Constants.java b/app/src/main/java/awais/instagrabber/utils/Constants.java index b2ffd9f4..158ebd8f 100755 --- a/app/src/main/java/awais/instagrabber/utils/Constants.java +++ b/app/src/main/java/awais/instagrabber/utils/Constants.java @@ -71,4 +71,7 @@ public final class Constants { public static final String FDROID_SHA1_FINGERPRINT = "C1661EB8FD09F618307E687786D5E5056F65084D"; public static final String SKIPPED_VERSION = "skipped_version"; public static final String DEFAULT_TAB = "default_tab"; + public static final String CHANNEL_ID = "InstaGrabber"; + public static final String CHANNEL_NAME = "Instagrabber"; + public static final String NOTIF_GROUP_NAME = "awais.instagrabber.InstaNotif"; } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/utils/CookieUtils.java b/app/src/main/java/awais/instagrabber/utils/CookieUtils.java new file mode 100644 index 00000000..92cf2004 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/utils/CookieUtils.java @@ -0,0 +1,148 @@ +package awais.instagrabber.utils; + +import android.util.Log; +import android.webkit.CookieManager; + +import androidx.annotation.Nullable; + +import java.net.CookiePolicy; +import java.net.CookieStore; +import java.net.HttpCookie; +import java.net.URI; +import java.net.URISyntaxException; + +import awais.instagrabber.BuildConfig; +import awaisomereport.LogCollector; + +public final class CookieUtils { + public static final CookieManager COOKIE_MANAGER = CookieManager.getInstance(); + public static final java.net.CookieManager NET_COOKIE_MANAGER = new java.net.CookieManager(null, CookiePolicy.ACCEPT_ALL); + + public static void setupCookies(final String cookieRaw) { + final CookieStore cookieStore = NET_COOKIE_MANAGER.getCookieStore(); + if (cookieStore == null || TextUtils.isEmpty(cookieRaw)) { + return; + } + if (cookieRaw.equals("LOGOUT")) { + cookieStore.removeAll(); + Utils.dataBox.deleteAllUserCookies(); + return; + } + try { + final URI uri1 = new URI("https://instagram.com"); + final URI uri2 = new URI("https://instagram.com/"); + final URI uri3 = new URI("https://i.instagram.com/"); + for (final String cookie : cookieRaw.split("; ")) { + final String[] strings = cookie.split("=", 2); + final HttpCookie httpCookie = new HttpCookie(strings[0].trim(), strings[1].trim()); + httpCookie.setDomain(".instagram.com"); + httpCookie.setPath("/"); + httpCookie.setVersion(0); + cookieStore.add(uri1, httpCookie); + cookieStore.add(uri2, httpCookie); + cookieStore.add(uri3, httpCookie); + } + } catch (final URISyntaxException e) { + if (Utils.logCollector != null) + Utils.logCollector.appendException(e, LogCollector.LogFile.UTILS, "setupCookies"); + if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); + } + } + + @Nullable + public static String getUserIdFromCookie(final String cookie) { + if (!TextUtils.isEmpty(cookie)) { + final int uidIndex = cookie.indexOf("ds_user_id="); + if (uidIndex > 0) { + String uid = cookie.split("ds_user_id=")[1].split(";")[0]; + return !TextUtils.isEmpty(uid) ? uid : null; + } + } + return null; + } + + public static String getCsrfTokenFromCookie(final String cookie) { + if (cookie == null) { + return null; + } + return cookie.split("csrftoken=")[1].split(";")[0]; + } + + @Nullable + public static String getCookie(@Nullable final String webViewUrl) { + int lastLongestCookieLength = 0; + String mainCookie = null; + + String cookie; + if (!TextUtils.isEmpty(webViewUrl)) { + cookie = COOKIE_MANAGER.getCookie(webViewUrl); + if (cookie != null) { + final int cookieLen = cookie.length(); + if (cookieLen > lastLongestCookieLength) { + mainCookie = cookie; + lastLongestCookieLength = cookieLen; + } + } + } + cookie = COOKIE_MANAGER.getCookie("https://instagram.com"); + if (cookie != null) { + final int cookieLen = cookie.length(); + if (cookieLen > lastLongestCookieLength) { + mainCookie = cookie; + lastLongestCookieLength = cookieLen; + } + } + cookie = COOKIE_MANAGER.getCookie("https://instagram.com/"); + if (cookie != null) { + final int cookieLen = cookie.length(); + if (cookieLen > lastLongestCookieLength) { + mainCookie = cookie; + lastLongestCookieLength = cookieLen; + } + } + cookie = COOKIE_MANAGER.getCookie("http://instagram.com"); + if (cookie != null) { + final int cookieLen = cookie.length(); + if (cookieLen > lastLongestCookieLength) { + mainCookie = cookie; + lastLongestCookieLength = cookieLen; + } + } + cookie = COOKIE_MANAGER.getCookie("http://instagram.com/"); + if (cookie != null) { + final int cookieLen = cookie.length(); + if (cookieLen > lastLongestCookieLength) { + mainCookie = cookie; + lastLongestCookieLength = cookieLen; + } + } + cookie = COOKIE_MANAGER.getCookie("https://www.instagram.com"); + if (cookie != null) { + final int cookieLen = cookie.length(); + if (cookieLen > lastLongestCookieLength) { + mainCookie = cookie; + lastLongestCookieLength = cookieLen; + } + } + cookie = COOKIE_MANAGER.getCookie("https://www.instagram.com/"); + if (cookie != null) { + final int cookieLen = cookie.length(); + if (cookieLen > lastLongestCookieLength) { + mainCookie = cookie; + lastLongestCookieLength = cookieLen; + } + } + cookie = COOKIE_MANAGER.getCookie("http://www.instagram.com"); + if (cookie != null) { + final int cookieLen = cookie.length(); + if (cookieLen > lastLongestCookieLength) { + mainCookie = cookie; + lastLongestCookieLength = cookieLen; + } + } + cookie = COOKIE_MANAGER.getCookie("http://www.instagram.com/"); + if (cookie != null && cookie.length() > lastLongestCookieLength) mainCookie = cookie; + + return mainCookie; + } +} diff --git a/app/src/main/java/awais/instagrabber/utils/DataBox.java b/app/src/main/java/awais/instagrabber/utils/DataBox.java index 93ed8153..d6bad63f 100755 --- a/app/src/main/java/awais/instagrabber/utils/DataBox.java +++ b/app/src/main/java/awais/instagrabber/utils/DataBox.java @@ -77,7 +77,7 @@ public final class DataBox extends SQLiteOpenHelper { public final void addFavorite(@NonNull final FavoriteModel favoriteModel) { final String query = favoriteModel.getQuery(); final String display = favoriteModel.getDisplayName(); - if (!Utils.isEmpty(query)) { + if (!TextUtils.isEmpty(query)) { try (final SQLiteDatabase db = getWritableDatabase()) { db.beginTransaction(); try { @@ -105,7 +105,7 @@ public final class DataBox extends SQLiteOpenHelper { public final synchronized void delFavorite(@NonNull final FavoriteModel favoriteModel) { final String query = favoriteModel.getQuery(); - if (!Utils.isEmpty(query)) { + if (!TextUtils.isEmpty(query)) { try (final SQLiteDatabase db = getWritableDatabase()) { db.beginTransaction(); try { @@ -202,7 +202,7 @@ public final class DataBox extends SQLiteOpenHelper { final String cookie, final String fullName, final String profilePicUrl) { - if (Utils.isEmpty(uid)) return; + if (TextUtils.isEmpty(uid)) return; try (final SQLiteDatabase db = getWritableDatabase()) { db.beginTransaction(); try { @@ -229,7 +229,7 @@ public final class DataBox extends SQLiteOpenHelper { public final synchronized void delUserCookie(@NonNull final CookieModel cookieModel) { final String cookieModelUid = cookieModel.getUid(); - if (!Utils.isEmpty(cookieModelUid)) { + if (!TextUtils.isEmpty(cookieModelUid)) { try (final SQLiteDatabase db = getWritableDatabase()) { db.beginTransaction(); try { diff --git a/app/src/main/java/awais/instagrabber/utils/DirectoryChooser.java b/app/src/main/java/awais/instagrabber/utils/DirectoryChooser.java index 9c912272..969029a1 100755 --- a/app/src/main/java/awais/instagrabber/utils/DirectoryChooser.java +++ b/app/src/main/java/awais/instagrabber/utils/DirectoryChooser.java @@ -46,7 +46,7 @@ public final class DirectoryChooser extends DialogFragment { } public DirectoryChooser setInitialDirectory(final String initialDirectory) { - if (!Utils.isEmpty(initialDirectory)) + if (!TextUtils.isEmpty(initialDirectory)) this.initialDirectory = initialDirectory; return this; } @@ -123,7 +123,7 @@ public final class DirectoryChooser extends DialogFragment { directoriesList.setAdapter(listDirectoriesAdapter); final File initDir = new File(initialDirectory); - final File initialDir = !Utils.isEmpty(initialDirectory) && isValidFile(initDir) ? initDir : Environment.getExternalStorageDirectory(); + final File initialDir = !TextUtils.isEmpty(initialDirectory) && isValidFile(initDir) ? initDir : Environment.getExternalStorageDirectory(); changeDirectory(initialDir); @@ -134,11 +134,11 @@ public final class DirectoryChooser extends DialogFragment { public void onCreate(@Nullable final Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (Utils.isEmpty(initialDirectory)) { + if (TextUtils.isEmpty(initialDirectory)) { initialDirectory = new File(sdcardPath, "Download").getAbsolutePath(); if (savedInstanceState != null) { final String savedDir = savedInstanceState.getString(KEY_CURRENT_DIRECTORY); - if (!Utils.isEmpty(savedDir)) initialDirectory = savedDir; + if (!TextUtils.isEmpty(savedDir)) initialDirectory = savedDir; } } diff --git a/app/src/main/java/awais/instagrabber/utils/DownloadUtils.java b/app/src/main/java/awais/instagrabber/utils/DownloadUtils.java new file mode 100644 index 00000000..4b867f87 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/utils/DownloadUtils.java @@ -0,0 +1,218 @@ +package awais.instagrabber.utils; + +import android.Manifest; +import android.app.Activity; +import android.content.Context; +import android.content.pm.PackageManager; +import android.os.AsyncTask; +import android.os.Environment; +import android.util.Log; +import android.util.Pair; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.List; +import java.util.regex.Pattern; + +import awais.instagrabber.BuildConfig; +import awais.instagrabber.R; +import awais.instagrabber.asyncs.DownloadAsync; +import awais.instagrabber.asyncs.PostFetcher; +import awais.instagrabber.models.BasePostModel; +import awais.instagrabber.models.StoryModel; +import awais.instagrabber.models.direct_messages.DirectItemModel; +import awais.instagrabber.models.enums.DownloadMethod; +import awais.instagrabber.models.enums.MediaItemType; +import awaisomereport.LogCollector; + +import static awais.instagrabber.utils.Constants.FOLDER_PATH; +import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO; + +public final class DownloadUtils { + public static final String[] PERMS = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}; + + public static void batchDownload(@NonNull final Context context, @Nullable String username, final DownloadMethod method, + final List itemsToDownload) { + if (Utils.settingsHelper == null) Utils.settingsHelper = new SettingsHelper(context); + + if (itemsToDownload == null || itemsToDownload.size() < 1) return; + + if (username != null && username.charAt(0) == '@') username = username.substring(1); + + if (ContextCompat.checkSelfPermission(context, PERMS[0]) == PackageManager.PERMISSION_GRANTED) + batchDownloadImpl(context, username, method, itemsToDownload); + else if (context instanceof Activity) + ActivityCompat.requestPermissions((Activity) context, PERMS, 8020); + } + + private static void batchDownloadImpl(@NonNull final Context context, + @Nullable final String username, + final DownloadMethod method, + final List itemsToDownload) { + File dir = new File(Environment.getExternalStorageDirectory(), "Download"); + + if (Utils.settingsHelper.getBoolean(FOLDER_SAVE_TO)) { + final String customPath = Utils.settingsHelper.getString(FOLDER_PATH); + if (!TextUtils.isEmpty(customPath)) dir = new File(customPath); + } + + if (Utils.settingsHelper.getBoolean(Constants.DOWNLOAD_USER_FOLDER) && !TextUtils.isEmpty(username)) + dir = new File(dir, username); + + if (!dir.exists() && !dir.mkdirs()) { + Toast.makeText(context, R.string.error_creating_folders, Toast.LENGTH_SHORT).show(); + return; + } + boolean checkEachPost = false; + switch (method) { + case DOWNLOAD_SAVED: + case DOWNLOAD_MAIN: + checkEachPost = true; + break; + case DOWNLOAD_FEED: + checkEachPost = false; + break; + } + final int itemsToDownloadSize = itemsToDownload.size(); + for (int i = 0; i < itemsToDownloadSize; i++) { + final BasePostModel selectedItem = itemsToDownload.get(i); + if (!checkEachPost) { + final boolean isSlider = itemsToDownloadSize > 1; + final File saveFile = getDownloadSaveFile(dir, selectedItem, isSlider ? "_slide_" + (i + 1) : ""); + new DownloadAsync(context, + selectedItem.getDisplayUrl(), + saveFile, + file -> selectedItem.setDownloaded(true)) + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } else { + final File finalDir = dir; + new PostFetcher(selectedItem.getShortCode(), result -> { + if (result != null) { + final int resultsSize = result.length; + final boolean multiResult = resultsSize > 1; + for (int j = 0; j < resultsSize; j++) { + final BasePostModel model = result[j]; + final File saveFile = getDownloadSaveFile(finalDir, model, multiResult ? "_slide_" + (j + 1) : ""); + new DownloadAsync(context, + model.getDisplayUrl(), + saveFile, + file -> model.setDownloaded(true)) + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + } + }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + } + } + + public static void dmDownload(@NonNull final Context context, @Nullable final String username, final DownloadMethod method, + final DirectItemModel.DirectItemMediaModel itemsToDownload) { + if (Utils.settingsHelper == null) Utils.settingsHelper = new SettingsHelper(context); + + if (itemsToDownload == null) return; + + if (ContextCompat.checkSelfPermission(context, PERMS[0]) == PackageManager.PERMISSION_GRANTED) + dmDownloadImpl(context, username, method, itemsToDownload); + else if (context instanceof Activity) + ActivityCompat.requestPermissions((Activity) context, PERMS, 8020); + } + + private static void dmDownloadImpl(@NonNull final Context context, @Nullable final String username, + final DownloadMethod method, final DirectItemModel.DirectItemMediaModel selectedItem) { + File dir = new File(Environment.getExternalStorageDirectory(), "Download"); + + if (Utils.settingsHelper.getBoolean(FOLDER_SAVE_TO)) { + final String customPath = Utils.settingsHelper.getString(FOLDER_PATH); + if (!TextUtils.isEmpty(customPath)) dir = new File(customPath); + } + + if (Utils.settingsHelper.getBoolean(Constants.DOWNLOAD_USER_FOLDER) && !TextUtils.isEmpty(username)) + dir = new File(dir, username); + + if (dir.exists() || dir.mkdirs()) { + new DownloadAsync(context, + selectedItem.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO ? selectedItem.getVideoUrl() : selectedItem.getThumbUrl(), + getDownloadSaveFileDm(dir, selectedItem, ""), + null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } else + Toast.makeText(context, R.string.error_creating_folders, Toast.LENGTH_SHORT).show(); + } + + @NonNull + private static File getDownloadSaveFile(final File finalDir, @NonNull final BasePostModel model, final String sliderPrefix) { + final String displayUrl = model.getDisplayUrl(); + return new File(finalDir, model.getPostId() + '_' + model.getPosition() + sliderPrefix + + getExtensionFromModel(displayUrl, model)); + } + + @NonNull + private static File getDownloadSaveFileDm(final File finalDir, + @NonNull final DirectItemModel.DirectItemMediaModel model, + final String sliderPrefix) { + final String displayUrl = model.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO ? model.getVideoUrl() : model.getThumbUrl(); + return new File(finalDir, model.getId() + sliderPrefix + + getExtensionFromModel(displayUrl, model)); + } + + @NonNull + public static String getExtensionFromModel(@NonNull final String url, final Object model) { + final String extension; + final int index = url.indexOf('?'); + + if (index != -1) extension = url.substring(index - 4, index); + else { + final boolean isVideo; + if (model instanceof StoryModel) + isVideo = ((StoryModel) model).getItemType() == MediaItemType.MEDIA_TYPE_VIDEO; + else if (model instanceof BasePostModel) + isVideo = ((BasePostModel) model).getItemType() == MediaItemType.MEDIA_TYPE_VIDEO; + else + isVideo = false; + extension = isVideo || url.contains(".mp4") ? ".mp4" : ".jpg"; + } + + return extension; + } + + public static void checkExistence(final File downloadDir, final File customDir, final boolean isSlider, + @NonNull final BasePostModel model) { + boolean exists = false; + + try { + final String displayUrl = model.getDisplayUrl(); + int index = displayUrl.indexOf('?'); + if (index < 0) { + return; + } + final String fileName = model.getPostId() + '_'; + final String extension = displayUrl.substring(index - 4, index); + + final String fileWithoutPrefix = fileName + '0' + extension; + exists = new File(downloadDir, fileWithoutPrefix).exists(); + if (!exists) { + final String fileWithPrefix = fileName + "[\\d]+(|_slide_[\\d]+)(\\.mp4|\\" + extension + ")"; + final FilenameFilter filenameFilter = (dir, name) -> Pattern.matches(fileWithPrefix, name); + + File[] files = downloadDir.listFiles(filenameFilter); + if ((files == null || files.length < 1) && customDir != null) + files = customDir.listFiles(filenameFilter); + + if (files != null && files.length >= 1) exists = true; + } + } catch (final Exception e) { + if (Utils.logCollector != null) + Utils.logCollector.appendException(e, LogCollector.LogFile.UTILS, "checkExistence", + new Pair<>("isSlider", isSlider), + new Pair<>("model", model)); + if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); + } + + model.setDownloaded(exists); + } +} diff --git a/app/src/main/java/awais/instagrabber/utils/ExportImportUtils.java b/app/src/main/java/awais/instagrabber/utils/ExportImportUtils.java index 73a42f41..4a81ede9 100755 --- a/app/src/main/java/awais/instagrabber/utils/ExportImportUtils.java +++ b/app/src/main/java/awais/instagrabber/utils/ExportImportUtils.java @@ -45,8 +45,8 @@ public final class ExportImportUtils { public static void Export(@Nullable final String password, @ExportImportFlags final int flags, @NonNull final File filePath, final FetchListener fetchListener) { final String exportString = ExportImportUtils.getExportString(flags); - if (!Utils.isEmpty(exportString)) { - final boolean isPass = !Utils.isEmpty(password); + if (!TextUtils.isEmpty(exportString)) { + final boolean isPass = !TextUtils.isEmpty(password); byte[] exportBytes = null; if (isPass) { @@ -100,7 +100,7 @@ public final class ExportImportUtils { new AlertDialog.Builder(context).setView(editText).setTitle(R.string.password) .setPositiveButton(R.string.confirm, (dialog, which) -> { final CharSequence text = editText.getText(); - if (!Utils.isEmpty(text)) { + if (!TextUtils.isEmpty(text)) { try { final byte[] passwordBytes = text.toString().getBytes(); final byte[] bytes = new byte[32]; @@ -228,16 +228,16 @@ public final class ExportImportUtils { json.put(Constants.APP_LANGUAGE, settingsHelper.getString(Constants.APP_LANGUAGE)); String str = settingsHelper.getString(Constants.FOLDER_PATH); - if (!Utils.isEmpty(str)) json.put(Constants.FOLDER_PATH, str); + if (!TextUtils.isEmpty(str)) json.put(Constants.FOLDER_PATH, str); str = settingsHelper.getString(Constants.DATE_TIME_FORMAT); - if (!Utils.isEmpty(str)) json.put(Constants.DATE_TIME_FORMAT, str); + if (!TextUtils.isEmpty(str)) json.put(Constants.DATE_TIME_FORMAT, str); str = settingsHelper.getString(Constants.DATE_TIME_SELECTION); - if (!Utils.isEmpty(str)) json.put(Constants.DATE_TIME_SELECTION, str); + if (!TextUtils.isEmpty(str)) json.put(Constants.DATE_TIME_SELECTION, str); str = settingsHelper.getString(Constants.CUSTOM_DATE_TIME_FORMAT); - if (!Utils.isEmpty(str)) json.put(Constants.CUSTOM_DATE_TIME_FORMAT, str); + if (!TextUtils.isEmpty(str)) json.put(Constants.CUSTOM_DATE_TIME_FORMAT, str); json.put(Constants.DOWNLOAD_USER_FOLDER, settingsHelper.getBoolean(Constants.DOWNLOAD_USER_FOLDER)); json.put(Constants.MUTED_VIDEOS, settingsHelper.getBoolean(Constants.MUTED_VIDEOS)); diff --git a/app/src/main/java/awais/instagrabber/utils/LocaleUtils.java b/app/src/main/java/awais/instagrabber/utils/LocaleUtils.java index a98ddc44..0d91bac3 100755 --- a/app/src/main/java/awais/instagrabber/utils/LocaleUtils.java +++ b/app/src/main/java/awais/instagrabber/utils/LocaleUtils.java @@ -22,7 +22,7 @@ public final class LocaleUtils { final String lang = LocaleUtils.getCorrespondingLanguageCode(baseContext); - currentLocale = Utils.isEmpty(lang) ? defaultLocale : new Locale(lang); + currentLocale = TextUtils.isEmpty(lang) ? defaultLocale : new Locale(lang); Locale.setDefault(currentLocale); final Resources res = baseContext.getResources(); @@ -56,7 +56,7 @@ public final class LocaleUtils { Utils.settingsHelper = new SettingsHelper(baseContext); final String appLanguageSettings = Utils.settingsHelper.getString(Constants.APP_LANGUAGE); - if (Utils.isEmpty(appLanguageSettings)) return null; + if (TextUtils.isEmpty(appLanguageSettings)) return null; final int appLanguageIndex = Integer.parseInt(appLanguageSettings); if (appLanguageIndex == 1) return "en"; diff --git a/app/src/main/java/awais/instagrabber/utils/NetworkUtils.java b/app/src/main/java/awais/instagrabber/utils/NetworkUtils.java new file mode 100644 index 00000000..e0fc0fe6 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/utils/NetworkUtils.java @@ -0,0 +1,50 @@ +package awais.instagrabber.utils; + +import androidx.annotation.NonNull; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.util.Map; +import java.util.Set; + +public final class NetworkUtils { + @NonNull + public static String readFromConnection(@NonNull final HttpURLConnection conn) throws Exception { + final StringBuilder sb = new StringBuilder(); + try (final BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) { + String line; + while ((line = br.readLine()) != null) sb.append(line).append('\n'); + } + return sb.toString(); + } + + public static void setConnectionHeaders(final HttpURLConnection connection, final Map headers) { + if (connection == null || headers == null || headers.isEmpty()) { + return; + } + for (Map.Entry header : headers.entrySet()) { + connection.setRequestProperty(header.getKey(), header.getValue()); + } + } + + public static String getQueryString(final Map queryParamsMap) { + if (queryParamsMap == null || queryParamsMap.isEmpty()) { + return ""; + } + final Set> params = queryParamsMap.entrySet(); + final StringBuilder builder = new StringBuilder(); + for (final Map.Entry param : params) { + if (TextUtils.isEmpty(param.getKey())) { + continue; + } + if (builder.length() != 0) { + builder.append("&"); + } + builder.append(param.getKey()); + builder.append("="); + builder.append(param.getValue() != null ? param.getValue() : ""); + } + return builder.toString(); + } +} diff --git a/app/src/main/java/awais/instagrabber/utils/NumberUtils.java b/app/src/main/java/awais/instagrabber/utils/NumberUtils.java new file mode 100644 index 00000000..37036f65 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/utils/NumberUtils.java @@ -0,0 +1,56 @@ +package awais.instagrabber.utils; + +import androidx.annotation.NonNull; + +import java.util.Random; + +public final class NumberUtils { + @NonNull + public static String millisToString(final long timeMs) { + final long totalSeconds = timeMs / 1000; + + final long seconds = totalSeconds % 60; + final long minutes = totalSeconds / 60 % 60; + final long hours = totalSeconds / 3600; + + final String strSec = Long.toString(seconds); + final String strMin = Long.toString(minutes); + + final String strRetSec = strSec.length() > 1 ? strSec : "0" + seconds; + final String strRetMin = strMin.length() > 1 ? strMin : "0" + minutes; + + final String retMinSec = strRetMin + ':' + strRetSec; + + if (hours > 0) + return Long.toString(hours) + ':' + retMinSec; + return retMinSec; + } + + public static int getResultingHeight(final int requiredWidth, final int height, final int width) { + return requiredWidth * height / width; + } + + public static int getResultingWidth(final int requiredHeight, final int height, final int width) { + return requiredHeight * width / height; + } + + public static long random(long origin, long bound) { + final Random random = new Random(); + long r = random.nextLong(); + long n = bound - origin, m = n - 1; + if ((n & m) == 0L) // power of two + r = (r & m) + origin; + else if (n > 0L) { // reject over-represented candidates + //noinspection StatementWithEmptyBody + for (long u = r >>> 1; // ensure non-negative + u + m - (r = u % n) < 0L; // rejection check + u = random.nextLong() >>> 1) // retry + ; + r += origin; + } else { // range not representable as long + while (r < origin || r >= bound) + r = random.nextLong(); + } + return r; + } +} diff --git a/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java b/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java new file mode 100644 index 00000000..a5610b22 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/utils/ResponseBodyUtils.java @@ -0,0 +1,562 @@ +package awais.instagrabber.utils; + +import android.util.Log; +import android.util.Pair; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Locale; + +import awais.instagrabber.BuildConfig; +import awais.instagrabber.models.ProfileModel; +import awais.instagrabber.models.direct_messages.DirectItemModel; +import awais.instagrabber.models.direct_messages.InboxThreadModel; +import awais.instagrabber.models.enums.DirectItemType; +import awais.instagrabber.models.enums.InboxReadState; +import awais.instagrabber.models.enums.MediaItemType; +import awais.instagrabber.models.enums.RavenExpiringMediaType; +import awais.instagrabber.models.enums.RavenMediaViewType; +import awaisomereport.LogCollector; + +public final class ResponseBodyUtils { + // isI: true if the content was requested from i.instagram.com instead of graphql + @Nullable + public static String getHighQualityPost(final JSONArray resources, final boolean isVideo, final boolean isI, final boolean low) { + try { + final int resourcesLen = resources.length(); + + final String[] sources = new String[resourcesLen]; + int lastResMain = low ? 1000000 : 0, lastIndexMain = -1; + int lastResBase = low ? 1000000 : 0, lastIndexBase = -1; + for (int i = 0; i < resourcesLen; ++i) { + final JSONObject item = resources.getJSONObject(i); + if (item != null && (!isVideo || item.has(Constants.EXTRAS_PROFILE) || isI)) { + sources[i] = item.getString(isI ? "url" : "src"); + final int currRes = item.getInt(isI ? "width" : "config_width") * item.getInt(isI ? "height" : "config_height"); + + final String profile = isVideo ? item.optString(Constants.EXTRAS_PROFILE) : null; + + if (!isVideo || "MAIN".equals(profile)) { + if (currRes > lastResMain && !low) { + lastResMain = currRes; + lastIndexMain = i; + } else if (currRes < lastResMain && low) { + lastResMain = currRes; + lastIndexMain = i; + } + } else { + if (currRes > lastResBase && !low) { + lastResBase = currRes; + lastIndexBase = i; + } else if (currRes < lastResBase && low) { + lastResBase = currRes; + lastIndexBase = i; + } + } + } + } + + if (lastIndexMain >= 0) return sources[lastIndexMain]; + else if (lastIndexBase >= 0) return sources[lastIndexBase]; + } catch (final Exception e) { + if (Utils.logCollector != null) + Utils.logCollector.appendException(e, LogCollector.LogFile.UTILS, "getHighQualityPost", + new Pair<>("resourcesNull", resources == null), + new Pair<>("isVideo", isVideo)); + if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); + } + return null; + } + + public static String getHighQualityImage(final JSONObject resources) { + String src = null; + try { + if (resources.has("display_resources")) + src = getHighQualityPost(resources.getJSONArray("display_resources"), false, false, false); + else if (resources.has("image_versions2")) + src = getHighQualityPost(resources.getJSONObject("image_versions2").getJSONArray("candidates"), false, true, false); + if (src == null) return resources.getString("display_url"); + } catch (final Exception e) { + if (Utils.logCollector != null) + Utils.logCollector.appendException(e, LogCollector.LogFile.UTILS, "getHighQualityImage", + new Pair<>("resourcesNull", resources == null)); + if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); + } + return src; + } + + public static String getLowQualityImage(final JSONObject resources) { + String src = null; + try { + src = getHighQualityPost(resources.getJSONObject("image_versions2").getJSONArray("candidates"), false, true, true); + } catch (final Exception e) { + if (Utils.logCollector != null) + Utils.logCollector.appendException(e, LogCollector.LogFile.UTILS, "getLowQualityImage", + new Pair<>("resourcesNull", resources == null)); + if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); + } + return src; + } + + public static String getItemThumbnail(@NonNull final JSONArray jsonArray) { + String thumbnail = null; + final int imageResLen = jsonArray.length(); + + for (int i = 0; i < imageResLen; ++i) { + final JSONObject imageResource = jsonArray.optJSONObject(i); + try { + final int width = imageResource.getInt("width"); + final int height = imageResource.getInt("height"); + final float ratio = Float.parseFloat(String.format(Locale.ENGLISH, "%.2f", (float) height / width)); + if (ratio >= 0.95f && ratio <= 1.0f) { + thumbnail = imageResource.getString("url"); + break; + } + } catch (final Exception e) { + if (Utils.logCollector != null) + Utils.logCollector.appendException(e, LogCollector.LogFile.UTILS, "getItemThumbnail"); + if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); + thumbnail = null; + } + } + + if (TextUtils.isEmpty(thumbnail)) thumbnail = jsonArray.optJSONObject(0).optString("url"); + + return thumbnail; + } + + @Nullable + public static String getThumbnailUrl(@NonNull final JSONObject mediaObj, final MediaItemType mediaType) throws Exception { + String thumbnail = null; + + if (mediaType == MediaItemType.MEDIA_TYPE_IMAGE || mediaType == MediaItemType.MEDIA_TYPE_VIDEO) { + final JSONObject imageVersions = mediaObj.optJSONObject("image_versions2"); + if (imageVersions != null) + thumbnail = getItemThumbnail(imageVersions.getJSONArray("candidates")); + + } else if (mediaType == MediaItemType.MEDIA_TYPE_SLIDER) { + final JSONArray carouselMedia = mediaObj.optJSONArray("carousel_media"); + if (carouselMedia != null) + thumbnail = getItemThumbnail(carouselMedia.getJSONObject(0) + .getJSONObject("image_versions2").getJSONArray("candidates")); + } + + return thumbnail; + } + + public static String getVideoUrl(@NonNull final JSONObject mediaObj) throws Exception { + String thumbnail = null; + + final JSONArray imageVersions = mediaObj.optJSONArray("video_versions"); + if (imageVersions != null) + thumbnail = getItemThumbnail(imageVersions); + + return thumbnail; + } + + @Nullable + public static MediaItemType getMediaItemType(final int mediaType) { + if (mediaType == 1) return MediaItemType.MEDIA_TYPE_IMAGE; + if (mediaType == 2) return MediaItemType.MEDIA_TYPE_VIDEO; + if (mediaType == 8) return MediaItemType.MEDIA_TYPE_SLIDER; + if (mediaType == 11) return MediaItemType.MEDIA_TYPE_VOICE; + return null; + } + + public static DirectItemModel.DirectItemMediaModel getDirectMediaModel(final JSONObject mediaObj) throws Exception { + final DirectItemModel.DirectItemMediaModel mediaModel; + if (mediaObj == null) mediaModel = null; + else { + final JSONObject userObj = mediaObj.optJSONObject("user"); + + ProfileModel user = null; + if (userObj != null) { + user = new ProfileModel( + userObj.getBoolean("is_private"), + false, + userObj.optBoolean("is_verified"), + String.valueOf(userObj.get("pk")), + userObj.getString("username"), + userObj.getString("full_name"), + null, null, + userObj.getString("profile_pic_url"), + null, 0, 0, 0, false, false, false, false); + } + + final MediaItemType mediaType = getMediaItemType(mediaObj.optInt("media_type", -1)); + + String id = mediaObj.optString("id"); + if (TextUtils.isEmpty(id)) id = null; + + mediaModel = new DirectItemModel.DirectItemMediaModel(mediaType, + mediaObj.optLong("expiring_at"), + mediaObj.optLong("pk"), + id, + getThumbnailUrl(mediaObj, mediaType), + mediaType == MediaItemType.MEDIA_TYPE_VIDEO ? getVideoUrl(mediaObj) : null, + user, + mediaObj.optString("code")); + } + return mediaModel; + } + + private static DirectItemType getDirectItemType(final String itemType) { + if ("placeholder".equals(itemType)) return DirectItemType.PLACEHOLDER; + if ("media".equals(itemType)) return DirectItemType.MEDIA; + if ("link".equals(itemType)) return DirectItemType.LINK; + if ("like".equals(itemType)) return DirectItemType.LIKE; + if ("reel_share".equals(itemType)) return DirectItemType.REEL_SHARE; + if ("media_share".equals(itemType)) return DirectItemType.MEDIA_SHARE; + if ("action_log".equals(itemType)) return DirectItemType.ACTION_LOG; + if ("raven_media".equals(itemType)) return DirectItemType.RAVEN_MEDIA; + if ("profile".equals(itemType)) return DirectItemType.PROFILE; + if ("video_call_event".equals(itemType)) return DirectItemType.VIDEO_CALL_EVENT; + if ("animated_media".equals(itemType)) return DirectItemType.ANIMATED_MEDIA; + if ("voice_media".equals(itemType)) return DirectItemType.VOICE_MEDIA; + if ("story_share".equals(itemType)) return DirectItemType.STORY_SHARE; + if ("clip".equals(itemType)) return DirectItemType.CLIP; + return DirectItemType.TEXT; + } + + @NonNull + public static InboxThreadModel createInboxThreadModel(@NonNull final JSONObject data, final boolean inThreadView) throws Exception { + final InboxReadState readState = data.getInt("read_state") == 0 ? InboxReadState.STATE_READ : InboxReadState.STATE_UNREAD; + final String threadType = data.getString("thread_type"); // they're all "private", group is identified by boolean "is_group" + + final String threadId = data.getString("thread_id"); + final String threadV2Id = data.getString("thread_v2_id"); + final String threadTitle = data.getString("thread_title"); + + final String threadNewestCursor = data.getString("newest_cursor"); + final String threadOldestCursor = data.getString("oldest_cursor"); + final String threadNextCursor = data.has("next_cursor") ? data.getString("next_cursor") : null; + final String threadPrevCursor = data.has("prev_cursor") ? data.getString("prev_cursor") : null; + + final boolean threadHasOlder = data.getBoolean("has_older"); + final long unreadCount = data.optLong("read_state", 0); + + final long lastActivityAt = data.optLong("last_activity_at"); + final boolean named = data.optBoolean("named"); + final boolean muted = data.optBoolean("muted"); + final boolean isPin = data.optBoolean("is_pin"); + final boolean isSpam = data.optBoolean("is_spam"); + final boolean isGroup = data.optBoolean("is_group"); + final boolean pending = data.optBoolean("pending"); + final boolean archived = data.optBoolean("archived"); + final boolean canonical = data.optBoolean("canonical"); + + final JSONArray users = data.getJSONArray("users"); + final int usersLen = users.length(); + final JSONArray leftusers = data.getJSONArray("left_users"); + final int leftusersLen = leftusers.length(); + final JSONArray admins = data.getJSONArray("admin_user_ids"); + final int adminsLen = admins.length(); + + final ProfileModel[] userModels = new ProfileModel[usersLen]; + for (int j = 0; j < usersLen; ++j) { + final JSONObject userObject = users.getJSONObject(j); + userModels[j] = new ProfileModel(userObject.getBoolean("is_private"), + false, + userObject.optBoolean("is_verified"), + String.valueOf(userObject.get("pk")), + userObject.getString("username"), + userObject.getString("full_name"), + null, null, + userObject.getString("profile_pic_url"), + null, 0, 0, 0, false, false, false, false); + } + + final ProfileModel[] leftuserModels = new ProfileModel[leftusersLen]; + for (int j = 0; j < leftusersLen; ++j) { + final JSONObject userObject = leftusers.getJSONObject(j); + leftuserModels[j] = new ProfileModel(userObject.getBoolean("is_private"), + false, + userObject.optBoolean("is_verified"), + String.valueOf(userObject.get("pk")), + userObject.getString("username"), + userObject.getString("full_name"), + null, null, + userObject.getString("profile_pic_url"), + null, 0, 0, 0, false, false, false, false); + } + + final Long[] adminIDs = new Long[adminsLen]; + for (int j = 0; j < adminsLen; ++j) { + adminIDs[j] = admins.getLong(j); + } + + final JSONArray items = data.getJSONArray("items"); + final int itemsLen = items.length(); + + final ArrayList itemModels = new ArrayList<>(itemsLen); + for (int i = 0; i < itemsLen; ++i) { + final JSONObject itemObject = items.getJSONObject(i); + + CharSequence text = null; + ProfileModel profileModel = null; + DirectItemModel.DirectItemLinkModel linkModel = null; + DirectItemModel.DirectItemMediaModel directMedia = null; + DirectItemModel.DirectItemReelShareModel reelShareModel = null; + DirectItemModel.DirectItemActionLogModel actionLogModel = null; + DirectItemModel.DirectItemAnimatedMediaModel animatedMediaModel = null; + DirectItemModel.DirectItemVoiceMediaModel voiceMediaModel = null; + DirectItemModel.DirectItemRavenMediaModel ravenMediaModel = null; + DirectItemModel.DirectItemVideoCallEventModel videoCallEventModel = null; + + final DirectItemType itemType = getDirectItemType(itemObject.getString("item_type")); + switch (itemType) { + case ANIMATED_MEDIA: { + final JSONObject animatedMedia = itemObject.getJSONObject("animated_media"); + final JSONObject stickerImage = animatedMedia.getJSONObject("images").getJSONObject("fixed_height"); + + animatedMediaModel = new DirectItemModel.DirectItemAnimatedMediaModel(animatedMedia.getBoolean("is_random"), + animatedMedia.getBoolean("is_sticker"), + animatedMedia.getString("id"), + stickerImage.getString("url"), + stickerImage.optString("webp"), + stickerImage.optString("mp4"), + stickerImage.getInt("height"), + stickerImage.getInt("width")); + } + break; + + case VOICE_MEDIA: { + final JSONObject voiceMedia = itemObject.getJSONObject("voice_media").getJSONObject("media"); + final JSONObject audio = voiceMedia.getJSONObject("audio"); + + int[] waveformData = null; + final JSONArray waveformDataArray = audio.optJSONArray("waveform_data"); + if (waveformDataArray != null) { + final int waveformDataLen = waveformDataArray.length(); + waveformData = new int[waveformDataLen]; + // 0.011775206 + for (int j = 0; j < waveformDataLen; ++j) { + waveformData[j] = (int) (waveformDataArray.optDouble(j) * 10); + } + } + + voiceMediaModel = new DirectItemModel.DirectItemVoiceMediaModel(voiceMedia.getString("id"), + audio.getString("audio_src"), audio.getLong("duration"), + waveformData); + } + break; + + case LINK: { + final JSONObject linkObj = itemObject.getJSONObject("link"); + + DirectItemModel.DirectItemLinkContext itemLinkContext = null; + final JSONObject linkContext = linkObj.optJSONObject("link_context"); + if (linkContext != null) { + itemLinkContext = new DirectItemModel.DirectItemLinkContext( + linkContext.getString("link_url"), + linkContext.optString("link_title"), + linkContext.optString("link_summary"), + linkContext.optString("link_image_url") + ); + } + + linkModel = new DirectItemModel.DirectItemLinkModel(linkObj.getString("text"), + linkObj.getString("client_context"), + linkObj.optString("mutation_token"), + itemLinkContext); + } + break; + + case REEL_SHARE: { + final JSONObject reelShare = itemObject.getJSONObject("reel_share"); + reelShareModel = new DirectItemModel.DirectItemReelShareModel( + reelShare.optBoolean("is_reel_persisted"), + reelShare.getLong("reel_owner_id"), + reelShare.getJSONObject("media").getJSONObject("user").getString("username"), + reelShare.getString("text"), + reelShare.getString("type"), + reelShare.getString("reel_type"), + reelShare.optString("reel_name"), + reelShare.optString("reel_id"), + getDirectMediaModel(reelShare.optJSONObject("media"))); + } + break; + + case RAVEN_MEDIA: { + final JSONObject visualMedia = itemObject.getJSONObject("visual_media"); + + final JSONArray seenUserIdsArray = visualMedia.getJSONArray("seen_user_ids"); + final int seenUsersLen = seenUserIdsArray.length(); + final String[] seenUserIds = new String[seenUsersLen]; + for (int j = 0; j < seenUsersLen; j++) + seenUserIds[j] = seenUserIdsArray.getString(j); + + DirectItemModel.RavenExpiringMediaActionSummaryModel expiringSummaryModel = null; + final JSONObject actionSummary = visualMedia.optJSONObject("expiring_media_action_summary"); + if (actionSummary != null) + expiringSummaryModel = new DirectItemModel.RavenExpiringMediaActionSummaryModel( + actionSummary.getLong("timestamp"), actionSummary.getInt("count"), + getExpiringMediaType(actionSummary.getString("type"))); + + final RavenMediaViewType viewType; + final String viewMode = visualMedia.getString("view_mode"); + switch (viewMode) { + case "replayable": + viewType = RavenMediaViewType.REPLAYABLE; + break; + case "permanent": + viewType = RavenMediaViewType.PERMANENT; + break; + case "once": + default: + viewType = RavenMediaViewType.ONCE; + } + + ravenMediaModel = new DirectItemModel.DirectItemRavenMediaModel( + visualMedia.optLong(viewType == RavenMediaViewType.PERMANENT ? "url_expire_at_secs" : "replay_expiring_at_us"), + visualMedia.optInt("playback_duration_secs"), + visualMedia.getInt("seen_count"), + seenUserIds, + viewType, + getDirectMediaModel(visualMedia.optJSONObject("media")), + expiringSummaryModel); + + } + break; + + case VIDEO_CALL_EVENT: { + final JSONObject videoCallEvent = itemObject.getJSONObject("video_call_event"); + videoCallEventModel = new DirectItemModel.DirectItemVideoCallEventModel(videoCallEvent.getLong("vc_id"), + videoCallEvent.optBoolean("thread_has_audio_only_call"), + videoCallEvent.getString("action"), + videoCallEvent.getString("description")); + } + break; + + case PROFILE: { + final JSONObject profile = itemObject.getJSONObject("profile"); + profileModel = new ProfileModel(profile.getBoolean("is_private"), + false, + profile.getBoolean("is_verified"), + Long.toString(profile.getLong("pk")), + profile.getString("username"), + profile.getString("full_name"), + null, null, + profile.getString("profile_pic_url"), + null, 0, 0, 0, false, false, false, false); + } + break; + + case PLACEHOLDER: + final JSONObject placeholder = itemObject.getJSONObject("placeholder"); + text = placeholder.getString("title") + "
" + placeholder.getString("message") + ""; + break; + + case ACTION_LOG: + if (inThreadView && itemObject.optInt("hide_in_thread", 0) != 0) + continue; + final JSONObject actionLog = itemObject.getJSONObject("action_log"); + String desc = actionLog.getString("description"); + JSONArray bold = actionLog.getJSONArray("bold"); + for (int q = 0; q < bold.length(); ++q) { + JSONObject boldItem = bold.getJSONObject(q); + desc = desc.substring(0, boldItem.getInt("start") + q * 7) + "" + + desc.substring(boldItem.getInt("start") + q * 7, boldItem.getInt("end") + q * 7) + + "" + desc.substring(boldItem.getInt("end") + q * 7); + } + actionLogModel = new DirectItemModel.DirectItemActionLogModel(desc); + break; + + case MEDIA_SHARE: + directMedia = getDirectMediaModel(itemObject.getJSONObject("media_share")); + break; + + case CLIP: + directMedia = getDirectMediaModel(itemObject.getJSONObject("clip").getJSONObject("clip")); + break; + + case MEDIA: + directMedia = getDirectMediaModel(itemObject.optJSONObject("media")); + break; + + case LIKE: + text = itemObject.getString("like"); + break; + + case STORY_SHARE: + final JSONObject storyShare = itemObject.getJSONObject("story_share"); + if (!storyShare.has("media")) + text = "" + storyShare.optString("message") + ""; + else { + reelShareModel = new DirectItemModel.DirectItemReelShareModel( + storyShare.optBoolean("is_reel_persisted"), + storyShare.getJSONObject("media").getJSONObject("user").getLong("pk"), + storyShare.getJSONObject("media").getJSONObject("user").getString("username"), + storyShare.getString("text"), + storyShare.getString("story_share_type"), + storyShare.getString("reel_type"), + storyShare.optString("reel_name"), + storyShare.optString("reel_id"), + getDirectMediaModel(storyShare.optJSONObject("media"))); + } + break; + + case TEXT: + if (!itemObject.has("text")) + Log.d("AWAISKING_APP", "itemObject: " + itemObject); // todo + text = itemObject.optString("text"); + break; + } + + String[] liked = null; + if (!itemObject.isNull("reactions") && !itemObject.getJSONObject("reactions").isNull("likes")) { + JSONArray rawLiked = itemObject.getJSONObject("reactions").getJSONArray("likes"); + liked = new String[rawLiked.length()]; + for (int l = 0; l < rawLiked.length(); ++l) { + liked[l] = String.valueOf(rawLiked.getJSONObject(l).getLong("sender_id")); + } + } + + itemModels.add(new DirectItemModel( + itemObject.getLong("user_id"), + itemObject.getLong("timestamp"), + itemObject.getString("item_id"), + liked, + itemType, + text, + linkModel, + profileModel, + reelShareModel, + directMedia, + actionLogModel, + voiceMediaModel, + ravenMediaModel, + videoCallEventModel, + animatedMediaModel)); + } + + itemModels.trimToSize(); + + return new InboxThreadModel(readState, threadId, threadV2Id, threadType, threadTitle, + threadNewestCursor, threadOldestCursor, threadNextCursor, threadPrevCursor, + null, // todo + userModels, leftuserModels, adminIDs, + itemModels.toArray(new DirectItemModel[0]), + muted, isPin, named, canonical, + pending, threadHasOlder, unreadCount, isSpam, isGroup, archived, lastActivityAt); + } + + private static RavenExpiringMediaType getExpiringMediaType(final String type) { + if ("raven_sent".equals(type)) return RavenExpiringMediaType.RAVEN_SENT; + if ("raven_opened".equals(type)) return RavenExpiringMediaType.RAVEN_OPENED; + if ("raven_blocked".equals(type)) return RavenExpiringMediaType.RAVEN_BLOCKED; + if ("raven_sending".equals(type)) return RavenExpiringMediaType.RAVEN_SENDING; + if ("raven_replayed".equals(type)) return RavenExpiringMediaType.RAVEN_REPLAYED; + if ("raven_delivered".equals(type)) return RavenExpiringMediaType.RAVEN_DELIVERED; + if ("raven_suggested".equals(type)) return RavenExpiringMediaType.RAVEN_SUGGESTED; + if ("raven_screenshot".equals(type)) return RavenExpiringMediaType.RAVEN_SCREENSHOT; + if ("raven_cannot_deliver".equals(type)) return RavenExpiringMediaType.RAVEN_CANNOT_DELIVER; + //if ("raven_unknown".equals(type)) [default?] + return RavenExpiringMediaType.RAVEN_UNKNOWN; + } +} diff --git a/app/src/main/java/awais/instagrabber/utils/TextUtils.java b/app/src/main/java/awais/instagrabber/utils/TextUtils.java new file mode 100644 index 00000000..b93a8304 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/utils/TextUtils.java @@ -0,0 +1,112 @@ +package awais.instagrabber.utils; + +import android.text.SpannableString; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.style.URLSpan; + +import androidx.annotation.NonNull; + +import awais.instagrabber.customviews.CommentMentionClickSpan; + +public final class TextUtils { + @NonNull + public static CharSequence getMentionText(@NonNull final CharSequence text) { + final int commentLength = text.length(); + final SpannableStringBuilder stringBuilder = new SpannableStringBuilder(text, 0, commentLength); + + for (int i = 0; i < commentLength; ++i) { + char currChar = text.charAt(i); + + if (currChar == '@' || currChar == '#') { + final int startLen = i; + + do { + if (++i == commentLength) break; + currChar = text.charAt(i); + + if (currChar == '.' && i + 1 < commentLength) { + final char nextChar = text.charAt(i + 1); + if (nextChar == '.' || nextChar == ' ' || nextChar == '#' || nextChar == '@' || nextChar == '/' + || nextChar == '\r' || nextChar == '\n') { + break; + } + } else if (currChar == '.') + break; + + // for merged hashtags + if (currChar == '#') { + --i; + break; + } + } while (currChar != ' ' && currChar != '\r' && currChar != '\n' && currChar != '>' && currChar != '<' + && currChar != ':' && currChar != ';' && currChar != '\'' && currChar != '"' && currChar != '[' + && currChar != ']' && currChar != '\\' && currChar != '=' && currChar != '-' && currChar != '!' + && currChar != '$' && currChar != '%' && currChar != '^' && currChar != '&' && currChar != '*' + && currChar != '(' && currChar != ')' && currChar != '{' && currChar != '}' && currChar != '/' + && currChar != '|' && currChar != '?' && currChar != '`' && currChar != '~' + ); + + final int endLen = currChar != '#' ? i : i + 1; // for merged hashtags + stringBuilder.setSpan(new CommentMentionClickSpan(), startLen, + Math.min(commentLength, endLen), // fixed - crash when end index is greater than comment length ( @kernoeb ) + Spanned.SPAN_EXCLUSIVE_INCLUSIVE); + } + } + + return stringBuilder; + } + + // extracted from String class + public static int indexOfChar(@NonNull final CharSequence sequence, final int ch, final int startIndex) { + final int max = sequence.length(); + if (startIndex < max) { + if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { + for (int i = startIndex; i < max; i++) if (sequence.charAt(i) == ch) return i; + } else if (Character.isValidCodePoint(ch)) { + final char hi = (char) ((ch >>> 10) + (Character.MIN_HIGH_SURROGATE - (Character.MIN_SUPPLEMENTARY_CODE_POINT >>> 10))); + final char lo = (char) ((ch & 0x3ff) + Character.MIN_LOW_SURROGATE); + for (int i = startIndex; i < max; i++) + if (sequence.charAt(i) == hi && sequence.charAt(i + 1) == lo) return i; + } + } + return -1; + } + + public static boolean hasMentions(final CharSequence text) { + if (isEmpty(text)) return false; + return indexOfChar(text, '@', 0) != -1 || indexOfChar(text, '#', 0) != -1; + } + + public static CharSequence getSpannableUrl(final String url) { + if (isEmpty(url)) return url; + final int httpIndex = url.indexOf("http:"); + final int httpsIndex = url.indexOf("https:"); + if (httpIndex == -1 && httpsIndex == -1) return url; + + final int length = url.length(); + + final int startIndex = httpIndex != -1 ? httpIndex : httpsIndex; + final int spaceIndex = url.indexOf(' ', startIndex + 1); + + final int endIndex = (spaceIndex != -1 ? spaceIndex : length); + + final String extractUrl = url.substring(startIndex, Math.min(length, endIndex)); + + final SpannableString spannableString = new SpannableString(url); + spannableString.setSpan(new URLSpan(extractUrl), startIndex, endIndex, 0); + + return spannableString; + } + + public static boolean isEmpty(final CharSequence charSequence) { + if (charSequence == null || charSequence.length() < 1) return true; + if (charSequence instanceof String) { + String str = (String) charSequence; + if ("".equals(str) || "null".equals(str) || str.isEmpty()) return true; + str = str.trim(); + return "".equals(str) || "null".equals(str) || str.isEmpty(); + } + return "null".contentEquals(charSequence) || "".contentEquals(charSequence) || charSequence.length() < 1; + } +} diff --git a/app/src/main/java/awais/instagrabber/utils/UpdateChecker.java b/app/src/main/java/awais/instagrabber/utils/UpdateChecker.java index 765d9e82..ea39e370 100755 --- a/app/src/main/java/awais/instagrabber/utils/UpdateChecker.java +++ b/app/src/main/java/awais/instagrabber/utils/UpdateChecker.java @@ -35,7 +35,7 @@ public final class UpdateChecker extends AsyncTask { final int responseCode = conn.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { - final JSONObject data = new JSONObject(Utils.readFromConnection(conn)); + final JSONObject data = new JSONObject(NetworkUtils.readFromConnection(conn)); if (BuildConfig.VERSION_CODE < data.getInt("suggestedVersionCode")) { version = data.getJSONArray("packages").getJSONObject(0).getString("versionName"); return true; diff --git a/app/src/main/java/awais/instagrabber/utils/Utils.java b/app/src/main/java/awais/instagrabber/utils/Utils.java index 52bb5ba7..02069b59 100755 --- a/app/src/main/java/awais/instagrabber/utils/Utils.java +++ b/app/src/main/java/awais/instagrabber/utils/Utils.java @@ -1,7 +1,5 @@ package awais.instagrabber.utils; -import android.Manifest; -import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.content.ClipData; @@ -13,20 +11,12 @@ import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; import android.net.Uri; -import android.os.AsyncTask; import android.os.Build; -import android.os.Environment; import android.text.Editable; -import android.text.SpannableString; -import android.text.SpannableStringBuilder; -import android.text.Spanned; -import android.text.style.URLSpan; import android.util.DisplayMetrics; import android.util.Log; -import android.util.Pair; import android.view.LayoutInflater; import android.view.View; -import android.webkit.CookieManager; import android.webkit.MimeTypeMap; import android.widget.Toast; @@ -35,90 +25,39 @@ import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatDelegate; -import androidx.core.app.ActivityCompat; import androidx.core.app.NotificationManagerCompat; -import androidx.core.content.ContextCompat; import androidx.fragment.app.FragmentManager; import com.google.android.exoplayer2.database.ExoDatabaseProvider; import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor; import com.google.android.exoplayer2.upstream.cache.SimpleCache; -import org.json.JSONArray; import org.json.JSONObject; -import java.io.BufferedReader; import java.io.File; -import java.io.FilenameFilter; -import java.io.InputStreamReader; -import java.net.CookiePolicy; -import java.net.CookieStore; -import java.net.HttpCookie; -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URISyntaxException; import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; -import java.util.Locale; import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.regex.Pattern; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; -import awais.instagrabber.BuildConfig; import awais.instagrabber.R; -import awais.instagrabber.asyncs.DownloadAsync; -import awais.instagrabber.asyncs.PostFetcher; -import awais.instagrabber.customviews.CommentMentionClickSpan; import awais.instagrabber.databinding.DialogImportExportBinding; -import awais.instagrabber.models.BasePostModel; -import awais.instagrabber.models.ProfileModel; -import awais.instagrabber.models.StoryModel; -import awais.instagrabber.models.direct_messages.DirectItemModel; -import awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemRavenMediaModel; -import awais.instagrabber.models.direct_messages.InboxThreadModel; -import awais.instagrabber.models.enums.DirectItemType; -import awais.instagrabber.models.enums.DownloadMethod; -import awais.instagrabber.models.enums.InboxReadState; -import awais.instagrabber.models.enums.MediaItemType; -import awais.instagrabber.models.enums.NotificationType; -import awais.instagrabber.models.enums.RavenExpiringMediaType; -import awais.instagrabber.models.enums.RavenMediaViewType; import awaisomereport.LogCollector; -import static awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemActionLogModel; -import static awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemAnimatedMediaModel; -import static awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemLinkContext; -import static awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemLinkModel; -import static awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemMediaModel; -import static awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemReelShareModel; -import static awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemVideoCallEventModel; -import static awais.instagrabber.models.direct_messages.DirectItemModel.DirectItemVoiceMediaModel; -import static awais.instagrabber.models.direct_messages.DirectItemModel.RavenExpiringMediaActionSummaryModel; import static awais.instagrabber.utils.Constants.FOLDER_PATH; -import static awais.instagrabber.utils.Constants.FOLDER_SAVE_TO; public final class Utils { private static final String TAG = "Utils"; - private static final int MAX_BYTES = 10 * 1024 * 1024; + private static final int VIDEO_CACHE_MAX_BYTES = 10 * 1024 * 1024; public static LogCollector logCollector; public static SettingsHelper settingsHelper; public static DataBox dataBox; public static boolean sessionVolumeFull = false; - @SuppressLint("StaticFieldLeak") public static NotificationManagerCompat notificationManager; - public static final CookieManager COOKIE_MANAGER = CookieManager.getInstance(); - public static final String[] PERMS = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}; - public static final java.net.CookieManager NET_COOKIE_MANAGER = new java.net.CookieManager(null, CookiePolicy.ACCEPT_ALL); public static final MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton(); - public static final String CHANNEL_ID = "InstaGrabber", CHANNEL_NAME = "Instagrabber", - NOTIF_GROUP_NAME = "awais.instagrabber.InstaNotif"; public static boolean isChannelCreated = false; public static String telegramPackage; public static ClipboardManager clipboardManager; @@ -126,638 +65,6 @@ public final class Utils { public static SimpleDateFormat datetimeParser; public static SimpleCache simpleCache; - public static void setupCookies(final String cookieRaw) { - final CookieStore cookieStore = NET_COOKIE_MANAGER.getCookieStore(); - if (cookieStore == null || isEmpty(cookieRaw)) { - return; - } - if (cookieRaw.equals("LOGOUT")) { - cookieStore.removeAll(); - dataBox.deleteAllUserCookies(); - return; - } - try { - final URI uri1 = new URI("https://instagram.com"); - final URI uri2 = new URI("https://instagram.com/"); - final URI uri3 = new URI("https://i.instagram.com/"); - for (final String cookie : cookieRaw.split("; ")) { - final String[] strings = cookie.split("=", 2); - final HttpCookie httpCookie = new HttpCookie(strings[0].trim(), strings[1].trim()); - httpCookie.setDomain(".instagram.com"); - httpCookie.setPath("/"); - httpCookie.setVersion(0); - cookieStore.add(uri1, httpCookie); - cookieStore.add(uri2, httpCookie); - cookieStore.add(uri3, httpCookie); - } - } catch (final URISyntaxException e) { - if (logCollector != null) - logCollector.appendException(e, LogCollector.LogFile.UTILS, "setupCookies"); - if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); - } - } - - @Nullable - public static String getUserIdFromCookie(final String cookie) { - if (!isEmpty(cookie)) { - final int uidIndex = cookie.indexOf("ds_user_id="); - if (uidIndex > 0) { - String uid = cookie.split("ds_user_id=")[1].split(";")[0]; - return !isEmpty(uid) ? uid : null; - } - } - return null; - } - - - @NonNull - public static CharSequence getMentionText(@NonNull final CharSequence text) { - final int commentLength = text.length(); - final SpannableStringBuilder stringBuilder = new SpannableStringBuilder(text, 0, commentLength); - - for (int i = 0; i < commentLength; ++i) { - char currChar = text.charAt(i); - - if (currChar == '@' || currChar == '#') { - final int startLen = i; - - do { - if (++i == commentLength) break; - currChar = text.charAt(i); - - if (currChar == '.' && i + 1 < commentLength) { - final char nextChar = text.charAt(i + 1); - if (nextChar == '.' || nextChar == ' ' || nextChar == '#' || nextChar == '@' || nextChar == '/' - || nextChar == '\r' || nextChar == '\n') { - break; - } - } else if (currChar == '.') - break; - - // for merged hashtags - if (currChar == '#') { - --i; - break; - } - } while (currChar != ' ' && currChar != '\r' && currChar != '\n' && currChar != '>' && currChar != '<' - && currChar != ':' && currChar != ';' && currChar != '\'' && currChar != '"' && currChar != '[' - && currChar != ']' && currChar != '\\' && currChar != '=' && currChar != '-' && currChar != '!' - && currChar != '$' && currChar != '%' && currChar != '^' && currChar != '&' && currChar != '*' - && currChar != '(' && currChar != ')' && currChar != '{' && currChar != '}' && currChar != '/' - && currChar != '|' && currChar != '?' && currChar != '`' && currChar != '~' - ); - - final int endLen = currChar != '#' ? i : i + 1; // for merged hashtags - stringBuilder.setSpan(new CommentMentionClickSpan(), startLen, - Math.min(commentLength, endLen), // fixed - crash when end index is greater than comment length ( @kernoeb ) - Spanned.SPAN_EXCLUSIVE_INCLUSIVE); - } - } - - return stringBuilder; - } - - // isI: true if the content was requested from i.instagram.com instead of graphql - @Nullable - public static String getHighQualityPost(final JSONArray resources, final boolean isVideo, final boolean isI, final boolean low) { - try { - final int resourcesLen = resources.length(); - - final String[] sources = new String[resourcesLen]; - int lastResMain = low ? 1000000 : 0, lastIndexMain = -1; - int lastResBase = low ? 1000000 : 0, lastIndexBase = -1; - for (int i = 0; i < resourcesLen; ++i) { - final JSONObject item = resources.getJSONObject(i); - if (item != null && (!isVideo || item.has(Constants.EXTRAS_PROFILE) || isI)) { - sources[i] = item.getString(isI ? "url" : "src"); - final int currRes = item.getInt(isI ? "width" : "config_width") * item.getInt(isI ? "height" : "config_height"); - - final String profile = isVideo ? item.optString(Constants.EXTRAS_PROFILE) : null; - - if (!isVideo || "MAIN".equals(profile)) { - if (currRes > lastResMain && !low) { - lastResMain = currRes; - lastIndexMain = i; - } else if (currRes < lastResMain && low) { - lastResMain = currRes; - lastIndexMain = i; - } - } else { - if (currRes > lastResBase && !low) { - lastResBase = currRes; - lastIndexBase = i; - } else if (currRes < lastResBase && low) { - lastResBase = currRes; - lastIndexBase = i; - } - } - } - } - - if (lastIndexMain >= 0) return sources[lastIndexMain]; - else if (lastIndexBase >= 0) return sources[lastIndexBase]; - } catch (final Exception e) { - if (logCollector != null) - logCollector.appendException(e, LogCollector.LogFile.UTILS, "getHighQualityPost", - new Pair<>("resourcesNull", resources == null), - new Pair<>("isVideo", isVideo)); - if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); - } - return null; - } - - public static String getHighQualityImage(final JSONObject resources) { - String src = null; - try { - if (resources.has("display_resources")) - src = getHighQualityPost(resources.getJSONArray("display_resources"), false, false, false); - else if (resources.has("image_versions2")) - src = getHighQualityPost(resources.getJSONObject("image_versions2").getJSONArray("candidates"), false, true, false); - if (src == null) return resources.getString("display_url"); - } catch (final Exception e) { - if (logCollector != null) - logCollector.appendException(e, LogCollector.LogFile.UTILS, "getHighQualityImage", - new Pair<>("resourcesNull", resources == null)); - if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); - } - return src; - } - - public static String getLowQualityImage(final JSONObject resources) { - String src = null; - try { - src = getHighQualityPost(resources.getJSONObject("image_versions2").getJSONArray("candidates"), false, true, true); - } catch (final Exception e) { - if (logCollector != null) - logCollector.appendException(e, LogCollector.LogFile.UTILS, "getLowQualityImage", - new Pair<>("resourcesNull", resources == null)); - if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); - } - return src; - } - - public static String getItemThumbnail(@NonNull final JSONArray jsonArray) { - String thumbnail = null; - final int imageResLen = jsonArray.length(); - - for (int i = 0; i < imageResLen; ++i) { - final JSONObject imageResource = jsonArray.optJSONObject(i); - try { - final int width = imageResource.getInt("width"); - final int height = imageResource.getInt("height"); - final float ratio = Float.parseFloat(String.format(Locale.ENGLISH, "%.2f", (float) height / width)); - if (ratio >= 0.95f && ratio <= 1.0f) { - thumbnail = imageResource.getString("url"); - break; - } - } catch (final Exception e) { - if (logCollector != null) - logCollector.appendException(e, LogCollector.LogFile.UTILS, "getItemThumbnail"); - if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); - thumbnail = null; - } - } - - if (Utils.isEmpty(thumbnail)) thumbnail = jsonArray.optJSONObject(0).optString("url"); - - return thumbnail; - } - - @Nullable - public static String getThumbnailUrl(@NonNull final JSONObject mediaObj, final MediaItemType mediaType) throws Exception { - String thumbnail = null; - - if (mediaType == MediaItemType.MEDIA_TYPE_IMAGE || mediaType == MediaItemType.MEDIA_TYPE_VIDEO) { - final JSONObject imageVersions = mediaObj.optJSONObject("image_versions2"); - if (imageVersions != null) - thumbnail = Utils.getItemThumbnail(imageVersions.getJSONArray("candidates")); - - } else if (mediaType == MediaItemType.MEDIA_TYPE_SLIDER) { - final JSONArray carouselMedia = mediaObj.optJSONArray("carousel_media"); - if (carouselMedia != null) - thumbnail = Utils.getItemThumbnail(carouselMedia.getJSONObject(0) - .getJSONObject("image_versions2").getJSONArray("candidates")); - } - - return thumbnail; - } - - public static String getVideoUrl(@NonNull final JSONObject mediaObj) throws Exception { - String thumbnail = null; - - final JSONArray imageVersions = mediaObj.optJSONArray("video_versions"); - if (imageVersions != null) - thumbnail = Utils.getItemThumbnail(imageVersions); - - return thumbnail; - } - - @Nullable - public static MediaItemType getMediaItemType(final int mediaType) { - if (mediaType == 1) return MediaItemType.MEDIA_TYPE_IMAGE; - if (mediaType == 2) return MediaItemType.MEDIA_TYPE_VIDEO; - if (mediaType == 8) return MediaItemType.MEDIA_TYPE_SLIDER; - if (mediaType == 11) return MediaItemType.MEDIA_TYPE_VOICE; - return null; - } - - public static DirectItemMediaModel getDirectMediaModel(final JSONObject mediaObj) throws Exception { - final DirectItemMediaModel mediaModel; - if (mediaObj == null) mediaModel = null; - else { - final JSONObject userObj = mediaObj.optJSONObject("user"); - - ProfileModel user = null; - if (userObj != null) { - user = new ProfileModel( - userObj.getBoolean("is_private"), - false, - userObj.optBoolean("is_verified"), - String.valueOf(userObj.get("pk")), - userObj.getString("username"), - userObj.getString("full_name"), - null, null, - userObj.getString("profile_pic_url"), - null, 0, 0, 0, false, false, false, false); - } - - final MediaItemType mediaType = getMediaItemType(mediaObj.optInt("media_type", -1)); - - String id = mediaObj.optString("id"); - if (Utils.isEmpty(id)) id = null; - - mediaModel = new DirectItemMediaModel(mediaType, - mediaObj.optLong("expiring_at"), - mediaObj.optLong("pk"), - id, - getThumbnailUrl(mediaObj, mediaType), - mediaType == MediaItemType.MEDIA_TYPE_VIDEO ? getVideoUrl(mediaObj) : null, - user, - mediaObj.optString("code")); - } - return mediaModel; - } - - private static DirectItemType getDirectItemType(final String itemType) { - if ("placeholder".equals(itemType)) return DirectItemType.PLACEHOLDER; - if ("media".equals(itemType)) return DirectItemType.MEDIA; - if ("link".equals(itemType)) return DirectItemType.LINK; - if ("like".equals(itemType)) return DirectItemType.LIKE; - if ("reel_share".equals(itemType)) return DirectItemType.REEL_SHARE; - if ("media_share".equals(itemType)) return DirectItemType.MEDIA_SHARE; - if ("action_log".equals(itemType)) return DirectItemType.ACTION_LOG; - if ("raven_media".equals(itemType)) return DirectItemType.RAVEN_MEDIA; - if ("profile".equals(itemType)) return DirectItemType.PROFILE; - if ("video_call_event".equals(itemType)) return DirectItemType.VIDEO_CALL_EVENT; - if ("animated_media".equals(itemType)) return DirectItemType.ANIMATED_MEDIA; - if ("voice_media".equals(itemType)) return DirectItemType.VOICE_MEDIA; - if ("story_share".equals(itemType)) return DirectItemType.STORY_SHARE; - if ("clip".equals(itemType)) return DirectItemType.CLIP; - return DirectItemType.TEXT; - } - - @NonNull - public static InboxThreadModel createInboxThreadModel(@NonNull final JSONObject data, final boolean inThreadView) throws Exception { - final InboxReadState readState = data.getInt("read_state") == 0 ? InboxReadState.STATE_READ : InboxReadState.STATE_UNREAD; - final String threadType = data.getString("thread_type"); // they're all "private", group is identified by boolean "is_group" - - final String threadId = data.getString("thread_id"); - final String threadV2Id = data.getString("thread_v2_id"); - final String threadTitle = data.getString("thread_title"); - - final String threadNewestCursor = data.getString("newest_cursor"); - final String threadOldestCursor = data.getString("oldest_cursor"); - final String threadNextCursor = data.has("next_cursor") ? data.getString("next_cursor") : null; - final String threadPrevCursor = data.has("prev_cursor") ? data.getString("prev_cursor") : null; - - final boolean threadHasOlder = data.getBoolean("has_older"); - final long unreadCount = data.optLong("read_state", 0); - - final long lastActivityAt = data.optLong("last_activity_at"); - final boolean named = data.optBoolean("named"); - final boolean muted = data.optBoolean("muted"); - final boolean isPin = data.optBoolean("is_pin"); - final boolean isSpam = data.optBoolean("is_spam"); - final boolean isGroup = data.optBoolean("is_group"); - final boolean pending = data.optBoolean("pending"); - final boolean archived = data.optBoolean("archived"); - final boolean canonical = data.optBoolean("canonical"); - - final JSONArray users = data.getJSONArray("users"); - final int usersLen = users.length(); - final JSONArray leftusers = data.getJSONArray("left_users"); - final int leftusersLen = leftusers.length(); - final JSONArray admins = data.getJSONArray("admin_user_ids"); - final int adminsLen = admins.length(); - - final ProfileModel[] userModels = new ProfileModel[usersLen]; - for (int j = 0; j < usersLen; ++j) { - final JSONObject userObject = users.getJSONObject(j); - userModels[j] = new ProfileModel(userObject.getBoolean("is_private"), - false, - userObject.optBoolean("is_verified"), - String.valueOf(userObject.get("pk")), - userObject.getString("username"), - userObject.getString("full_name"), - null, null, - userObject.getString("profile_pic_url"), - null, 0, 0, 0, false, false, false, false); - } - - final ProfileModel[] leftuserModels = new ProfileModel[leftusersLen]; - for (int j = 0; j < leftusersLen; ++j) { - final JSONObject userObject = leftusers.getJSONObject(j); - leftuserModels[j] = new ProfileModel(userObject.getBoolean("is_private"), - false, - userObject.optBoolean("is_verified"), - String.valueOf(userObject.get("pk")), - userObject.getString("username"), - userObject.getString("full_name"), - null, null, - userObject.getString("profile_pic_url"), - null, 0, 0, 0, false, false, false, false); - } - - final Long[] adminIDs = new Long[adminsLen]; - for (int j = 0; j < adminsLen; ++j) { - adminIDs[j] = admins.getLong(j); - } - - final JSONArray items = data.getJSONArray("items"); - final int itemsLen = items.length(); - - final ArrayList itemModels = new ArrayList<>(itemsLen); - for (int i = 0; i < itemsLen; ++i) { - final JSONObject itemObject = items.getJSONObject(i); - - CharSequence text = null; - ProfileModel profileModel = null; - DirectItemLinkModel linkModel = null; - DirectItemMediaModel directMedia = null; - DirectItemReelShareModel reelShareModel = null; - DirectItemActionLogModel actionLogModel = null; - DirectItemAnimatedMediaModel animatedMediaModel = null; - DirectItemVoiceMediaModel voiceMediaModel = null; - DirectItemRavenMediaModel ravenMediaModel = null; - DirectItemVideoCallEventModel videoCallEventModel = null; - - final DirectItemType itemType = getDirectItemType(itemObject.getString("item_type")); - switch (itemType) { - case ANIMATED_MEDIA: { - final JSONObject animatedMedia = itemObject.getJSONObject("animated_media"); - final JSONObject stickerImage = animatedMedia.getJSONObject("images").getJSONObject("fixed_height"); - - animatedMediaModel = new DirectItemAnimatedMediaModel(animatedMedia.getBoolean("is_random"), - animatedMedia.getBoolean("is_sticker"), animatedMedia.getString("id"), - stickerImage.getString("url"), stickerImage.optString("webp"), - stickerImage.optString("mp4"), - stickerImage.getInt("height"), stickerImage.getInt("width")); - } - break; - - case VOICE_MEDIA: { - final JSONObject voiceMedia = itemObject.getJSONObject("voice_media").getJSONObject("media"); - final JSONObject audio = voiceMedia.getJSONObject("audio"); - - int[] waveformData = null; - final JSONArray waveformDataArray = audio.optJSONArray("waveform_data"); - if (waveformDataArray != null) { - final int waveformDataLen = waveformDataArray.length(); - waveformData = new int[waveformDataLen]; - // 0.011775206 - for (int j = 0; j < waveformDataLen; ++j) { - waveformData[j] = (int) (waveformDataArray.optDouble(j) * 10); - } - } - - voiceMediaModel = new DirectItemVoiceMediaModel(voiceMedia.getString("id"), - audio.getString("audio_src"), audio.getLong("duration"), - waveformData); - } - break; - - case LINK: { - final JSONObject linkObj = itemObject.getJSONObject("link"); - - DirectItemLinkContext itemLinkContext = null; - final JSONObject linkContext = linkObj.optJSONObject("link_context"); - if (linkContext != null) { - itemLinkContext = new DirectItemLinkContext( - linkContext.getString("link_url"), - linkContext.optString("link_title"), - linkContext.optString("link_summary"), - linkContext.optString("link_image_url") - ); - } - - linkModel = new DirectItemLinkModel(linkObj.getString("text"), - linkObj.getString("client_context"), - linkObj.optString("mutation_token"), - itemLinkContext); - } - break; - - case REEL_SHARE: { - final JSONObject reelShare = itemObject.getJSONObject("reel_share"); - reelShareModel = new DirectItemReelShareModel( - reelShare.optBoolean("is_reel_persisted"), - reelShare.getLong("reel_owner_id"), - reelShare.getJSONObject("media").getJSONObject("user").getString("username"), - reelShare.getString("text"), - reelShare.getString("type"), - reelShare.getString("reel_type"), - reelShare.optString("reel_name"), - reelShare.optString("reel_id"), - getDirectMediaModel(reelShare.optJSONObject("media"))); - } - break; - - case RAVEN_MEDIA: { - final JSONObject visualMedia = itemObject.getJSONObject("visual_media"); - - final JSONArray seenUserIdsArray = visualMedia.getJSONArray("seen_user_ids"); - final int seenUsersLen = seenUserIdsArray.length(); - final String[] seenUserIds = new String[seenUsersLen]; - for (int j = 0; j < seenUsersLen; j++) - seenUserIds[j] = seenUserIdsArray.getString(j); - - RavenExpiringMediaActionSummaryModel expiringSummaryModel = null; - final JSONObject actionSummary = visualMedia.optJSONObject("expiring_media_action_summary"); - if (actionSummary != null) - expiringSummaryModel = new RavenExpiringMediaActionSummaryModel( - actionSummary.getLong("timestamp"), actionSummary.getInt("count"), - getExpiringMediaType(actionSummary.getString("type"))); - - final RavenMediaViewType viewType; - final String viewMode = visualMedia.getString("view_mode"); - switch (viewMode) { - case "replayable": - viewType = RavenMediaViewType.REPLAYABLE; - break; - case "permanent": - viewType = RavenMediaViewType.PERMANENT; - break; - case "once": - default: - viewType = RavenMediaViewType.ONCE; - } - - ravenMediaModel = new DirectItemRavenMediaModel( - visualMedia.optLong(viewType == RavenMediaViewType.PERMANENT ? "url_expire_at_secs" : "replay_expiring_at_us"), - visualMedia.optInt("playback_duration_secs"), - visualMedia.getInt("seen_count"), - seenUserIds, - viewType, - getDirectMediaModel(visualMedia.optJSONObject("media")), - expiringSummaryModel); - - } - break; - - case VIDEO_CALL_EVENT: { - final JSONObject videoCallEvent = itemObject.getJSONObject("video_call_event"); - videoCallEventModel = new DirectItemVideoCallEventModel(videoCallEvent.getLong("vc_id"), - videoCallEvent.optBoolean("thread_has_audio_only_call"), - videoCallEvent.getString("action"), - videoCallEvent.getString("description")); - } - break; - - case PROFILE: { - final JSONObject profile = itemObject.getJSONObject("profile"); - profileModel = new ProfileModel(profile.getBoolean("is_private"), - false, - profile.getBoolean("is_verified"), - Long.toString(profile.getLong("pk")), - profile.getString("username"), - profile.getString("full_name"), - null, null, - profile.getString("profile_pic_url"), - null, 0, 0, 0, false, false, false, false); - } - break; - - case PLACEHOLDER: - final JSONObject placeholder = itemObject.getJSONObject("placeholder"); - text = placeholder.getString("title") + "
" + placeholder.getString("message") + ""; - break; - - case ACTION_LOG: - if (inThreadView && itemObject.optInt("hide_in_thread", 0) != 0) - continue; - final JSONObject actionLog = itemObject.getJSONObject("action_log"); - String desc = actionLog.getString("description"); - JSONArray bold = actionLog.getJSONArray("bold"); - for (int q = 0; q < bold.length(); ++q) { - JSONObject boldItem = bold.getJSONObject(q); - desc = desc.substring(0, boldItem.getInt("start") + q * 7) + "" - + desc.substring(boldItem.getInt("start") + q * 7, boldItem.getInt("end") + q * 7) - + "" + desc.substring(boldItem.getInt("end") + q * 7); - } - actionLogModel = new DirectItemActionLogModel(desc); - break; - - case MEDIA_SHARE: - directMedia = getDirectMediaModel(itemObject.getJSONObject("media_share")); - break; - - case CLIP: - directMedia = getDirectMediaModel(itemObject.getJSONObject("clip").getJSONObject("clip")); - break; - - case MEDIA: - directMedia = getDirectMediaModel(itemObject.optJSONObject("media")); - break; - - case LIKE: - text = itemObject.getString("like"); - break; - - case STORY_SHARE: - final JSONObject storyShare = itemObject.getJSONObject("story_share"); - if (!storyShare.has("media")) - text = "" + storyShare.optString("message") + ""; - else { - reelShareModel = new DirectItemReelShareModel( - storyShare.optBoolean("is_reel_persisted"), - storyShare.getJSONObject("media").getJSONObject("user").getLong("pk"), - storyShare.getJSONObject("media").getJSONObject("user").getString("username"), - storyShare.getString("text"), - storyShare.getString("story_share_type"), - storyShare.getString("reel_type"), - storyShare.optString("reel_name"), - storyShare.optString("reel_id"), - getDirectMediaModel(storyShare.optJSONObject("media"))); - } - break; - - case TEXT: - if (!itemObject.has("text")) - Log.d("AWAISKING_APP", "itemObject: " + itemObject); // todo - text = itemObject.optString("text"); - break; - } - - String[] liked = null; - if (!itemObject.isNull("reactions") && !itemObject.getJSONObject("reactions").isNull("likes")) { - JSONArray rawLiked = itemObject.getJSONObject("reactions").getJSONArray("likes"); - liked = new String[rawLiked.length()]; - for (int l = 0; l < rawLiked.length(); ++l) { - liked[l] = String.valueOf(rawLiked.getJSONObject(l).getLong("sender_id")); - } - } - - itemModels.add(new DirectItemModel( - itemObject.getLong("user_id"), - itemObject.getLong("timestamp"), - itemObject.getString("item_id"), - liked, - itemType, - text, - linkModel, - profileModel, - reelShareModel, - directMedia, - actionLogModel, - voiceMediaModel, - ravenMediaModel, - videoCallEventModel, - animatedMediaModel)); - } - - itemModels.trimToSize(); - - return new InboxThreadModel(readState, threadId, threadV2Id, threadType, threadTitle, - threadNewestCursor, threadOldestCursor, threadNextCursor, threadPrevCursor, - null, // todo - userModels, leftuserModels, adminIDs, - itemModels.toArray(new DirectItemModel[0]), - muted, isPin, named, canonical, - pending, threadHasOlder, unreadCount, isSpam, isGroup, archived, lastActivityAt); - } - - private static RavenExpiringMediaType getExpiringMediaType(final String type) { - if ("raven_sent".equals(type)) return RavenExpiringMediaType.RAVEN_SENT; - if ("raven_opened".equals(type)) return RavenExpiringMediaType.RAVEN_OPENED; - if ("raven_blocked".equals(type)) return RavenExpiringMediaType.RAVEN_BLOCKED; - if ("raven_sending".equals(type)) return RavenExpiringMediaType.RAVEN_SENDING; - if ("raven_replayed".equals(type)) return RavenExpiringMediaType.RAVEN_REPLAYED; - if ("raven_delivered".equals(type)) return RavenExpiringMediaType.RAVEN_DELIVERED; - if ("raven_suggested".equals(type)) return RavenExpiringMediaType.RAVEN_SUGGESTED; - if ("raven_screenshot".equals(type)) return RavenExpiringMediaType.RAVEN_SCREENSHOT; - if ("raven_cannot_deliver".equals(type)) return RavenExpiringMediaType.RAVEN_CANNOT_DELIVER; - //if ("raven_unknown".equals(type)) [default?] - return RavenExpiringMediaType.RAVEN_UNKNOWN; - } - - public static NotificationType getNotifType(final String itemType) { - if ("GraphLikeAggregatedStory".equals(itemType)) return NotificationType.LIKE; - if ("GraphFollowAggregatedStory".equals(itemType)) return NotificationType.FOLLOW; - if ("GraphCommentMediaStory".equals(itemType)) return NotificationType.COMMENT; - if ("GraphMentionStory".equals(itemType)) return NotificationType.MENTION; - return null; - } - public static int convertDpToPx(final float dp) { if (displayMetrics == null) displayMetrics = Resources.getSystem().getDisplayMetrics(); @@ -797,7 +104,6 @@ public final class Utils { return isNight; } - public static void setTooltipText(final View view, @StringRes final int tooltipTextRes) { if (view != null && tooltipTextRes != 0 && tooltipTextRes != -1) { final Context context = view.getContext(); @@ -811,48 +117,6 @@ public final class Utils { } } - @NonNull - public static String millisToString(final long timeMs) { - final long totalSeconds = timeMs / 1000; - - final long seconds = totalSeconds % 60; - final long minutes = totalSeconds / 60 % 60; - final long hours = totalSeconds / 3600; - - final String strSec = Long.toString(seconds); - final String strMin = Long.toString(minutes); - - final String strRetSec = strSec.length() > 1 ? strSec : "0" + seconds; - final String strRetMin = strMin.length() > 1 ? strMin : "0" + minutes; - - final String retMinSec = strRetMin + ':' + strRetSec; - - if (hours > 0) - return Long.toString(hours) + ':' + retMinSec; - return retMinSec; - } - - // extracted from String class - public static int indexOfChar(@NonNull final CharSequence sequence, final int ch, final int startIndex) { - final int max = sequence.length(); - if (startIndex < max) { - if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { - for (int i = startIndex; i < max; i++) if (sequence.charAt(i) == ch) return i; - } else if (Character.isValidCodePoint(ch)) { - final char hi = (char) ((ch >>> 10) + (Character.MIN_HIGH_SURROGATE - (Character.MIN_SUPPLEMENTARY_CODE_POINT >>> 10))); - final char lo = (char) ((ch & 0x3ff) + Character.MIN_LOW_SURROGATE); - for (int i = startIndex; i < max; i++) - if (sequence.charAt(i) == hi && sequence.charAt(i + 1) == lo) return i; - } - } - return -1; - } - - public static boolean hasMentions(final CharSequence text) { - if (isEmpty(text)) return false; - return Utils.indexOfChar(text, '@', 0) != -1 || Utils.indexOfChar(text, '#', 0) != -1; - } - public static void copyText(final Context context, final CharSequence string) { final boolean ctxNotNull = context != null; if (ctxNotNull && clipboardManager == null) @@ -860,207 +124,12 @@ public final class Utils { int toastMessage = R.string.clipboard_error; if (clipboardManager != null) { - clipboardManager.setPrimaryClip(ClipData.newPlainText(Utils.CHANNEL_NAME, string)); + clipboardManager.setPrimaryClip(ClipData.newPlainText(Constants.CHANNEL_NAME, string)); toastMessage = R.string.clipboard_copied; } if (ctxNotNull) Toast.makeText(context, toastMessage, Toast.LENGTH_SHORT).show(); } - @NonNull - public static String readFromConnection(@NonNull final HttpURLConnection conn) throws Exception { - final StringBuilder sb = new StringBuilder(); - try (final BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) { - String line; - while ((line = br.readLine()) != null) sb.append(line).append('\n'); - } - return sb.toString(); - } - - public static void batchDownload(@NonNull final Context context, @Nullable String username, final DownloadMethod method, - final List itemsToDownload) { - if (settingsHelper == null) settingsHelper = new SettingsHelper(context); - - if (itemsToDownload == null || itemsToDownload.size() < 1) return; - - if (username != null && username.charAt(0) == '@') username = username.substring(1); - - if (ContextCompat.checkSelfPermission(context, Utils.PERMS[0]) == PackageManager.PERMISSION_GRANTED) - batchDownloadImpl(context, username, method, itemsToDownload); - else if (context instanceof Activity) - ActivityCompat.requestPermissions((Activity) context, Utils.PERMS, 8020); - } - - private static void batchDownloadImpl(@NonNull final Context context, - @Nullable final String username, - final DownloadMethod method, - final List itemsToDownload) { - File dir = new File(Environment.getExternalStorageDirectory(), "Download"); - - if (settingsHelper.getBoolean(FOLDER_SAVE_TO)) { - final String customPath = settingsHelper.getString(FOLDER_PATH); - if (!Utils.isEmpty(customPath)) dir = new File(customPath); - } - - if (settingsHelper.getBoolean(Constants.DOWNLOAD_USER_FOLDER) && !isEmpty(username)) - dir = new File(dir, username); - - if (!dir.exists() && !dir.mkdirs()) { - Toast.makeText(context, R.string.error_creating_folders, Toast.LENGTH_SHORT).show(); - return; - } - boolean checkEachPost = false; - switch (method) { - case DOWNLOAD_SAVED: - case DOWNLOAD_MAIN: - checkEachPost = true; - break; - case DOWNLOAD_FEED: - checkEachPost = false; - break; - } - final int itemsToDownloadSize = itemsToDownload.size(); - for (int i = 0; i < itemsToDownloadSize; i++) { - final BasePostModel selectedItem = itemsToDownload.get(i); - if (!checkEachPost) { - final boolean isSlider = itemsToDownloadSize > 1; - final File saveFile = getDownloadSaveFile(dir, selectedItem, isSlider ? "_slide_" + (i + 1) : ""); - new DownloadAsync(context, - selectedItem.getDisplayUrl(), - saveFile, - file -> selectedItem.setDownloaded(true)) - .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } else { - final File finalDir = dir; - new PostFetcher(selectedItem.getShortCode(), result -> { - if (result != null) { - final int resultsSize = result.length; - final boolean multiResult = resultsSize > 1; - for (int j = 0; j < resultsSize; j++) { - final BasePostModel model = result[j]; - final File saveFile = getDownloadSaveFile(finalDir, model, multiResult ? "_slide_" + (j + 1) : ""); - new DownloadAsync(context, - model.getDisplayUrl(), - saveFile, - file -> model.setDownloaded(true)) - .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - } - }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - } - } - - public static void dmDownload(@NonNull final Context context, @Nullable final String username, final DownloadMethod method, - final DirectItemMediaModel itemsToDownload) { - if (settingsHelper == null) settingsHelper = new SettingsHelper(context); - - if (itemsToDownload == null) return; - - if (ContextCompat.checkSelfPermission(context, Utils.PERMS[0]) == PackageManager.PERMISSION_GRANTED) - dmDownloadImpl(context, username, method, itemsToDownload); - else if (context instanceof Activity) - ActivityCompat.requestPermissions((Activity) context, Utils.PERMS, 8020); - } - - private static void dmDownloadImpl(@NonNull final Context context, @Nullable final String username, - final DownloadMethod method, final DirectItemMediaModel selectedItem) { - File dir = new File(Environment.getExternalStorageDirectory(), "Download"); - - if (settingsHelper.getBoolean(FOLDER_SAVE_TO)) { - final String customPath = settingsHelper.getString(FOLDER_PATH); - if (!Utils.isEmpty(customPath)) dir = new File(customPath); - } - - if (settingsHelper.getBoolean(Constants.DOWNLOAD_USER_FOLDER) && !isEmpty(username)) - dir = new File(dir, username); - - if (dir.exists() || dir.mkdirs()) { - new DownloadAsync(context, - selectedItem.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO ? selectedItem.getVideoUrl() : selectedItem.getThumbUrl(), - getDownloadSaveFileDm(dir, selectedItem, ""), - null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } else - Toast.makeText(context, R.string.error_creating_folders, Toast.LENGTH_SHORT).show(); - } - - @NonNull - private static File getDownloadSaveFile(final File finalDir, @NonNull final BasePostModel model, final String sliderPrefix) { - final String displayUrl = model.getDisplayUrl(); - return new File(finalDir, model.getPostId() + '_' + model.getPosition() + sliderPrefix + - getExtensionFromModel(displayUrl, model)); - } - - @NonNull - private static File getDownloadSaveFileDm(final File finalDir, @NonNull final DirectItemMediaModel model, final String sliderPrefix) { - final String displayUrl = model.getMediaType() == MediaItemType.MEDIA_TYPE_VIDEO ? model.getVideoUrl() : model.getThumbUrl(); - return new File(finalDir, model.getId() + sliderPrefix + - getExtensionFromModel(displayUrl, model)); - } - - @NonNull - public static String getExtensionFromModel(@NonNull final String url, final Object model) { - final String extension; - final int index = url.indexOf('?'); - - if (index != -1) extension = url.substring(index - 4, index); - else { - final boolean isVideo; - if (model instanceof StoryModel) - isVideo = ((StoryModel) model).getItemType() == MediaItemType.MEDIA_TYPE_VIDEO; - else if (model instanceof BasePostModel) - isVideo = ((BasePostModel) model).getItemType() == MediaItemType.MEDIA_TYPE_VIDEO; - else - isVideo = false; - extension = isVideo || url.contains(".mp4") ? ".mp4" : ".jpg"; - } - - return extension; - } - - public static void checkExistence(final File downloadDir, final File customDir, final boolean isSlider, - @NonNull final BasePostModel model) { - boolean exists = false; - - try { - final String displayUrl = model.getDisplayUrl(); - int index = displayUrl.indexOf('?'); - if (index < 0) { - return; - } - final String fileName = model.getPostId() + '_'; - final String extension = displayUrl.substring(index - 4, index); - - final String fileWithoutPrefix = fileName + '0' + extension; - exists = new File(downloadDir, fileWithoutPrefix).exists(); - if (!exists) { - final String fileWithPrefix = fileName + "[\\d]+(|_slide_[\\d]+)(\\.mp4|\\" + extension + ")"; - final FilenameFilter filenameFilter = (dir, name) -> Pattern.matches(fileWithPrefix, name); - - File[] files = downloadDir.listFiles(filenameFilter); - if ((files == null || files.length < 1) && customDir != null) - files = customDir.listFiles(filenameFilter); - - if (files != null && files.length >= 1) exists = true; - } - } catch (final Exception e) { - if (logCollector != null) - logCollector.appendException(e, LogCollector.LogFile.UTILS, "checkExistence", - new Pair<>("isSlider", isSlider), - new Pair<>("model", model)); - if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); - } - - model.setDownloaded(exists); - } - - public static boolean hasKey(final String key, final String username, final String name) { - if (!Utils.isEmpty(key)) { - final boolean hasUserName = username != null && username.toLowerCase().contains(key); - if (!hasUserName && name != null) return name.toLowerCase().contains(key); - } - return true; - } - public static void showImportExportDialog(final Context context) { final DialogImportExportBinding importExportBinding = DialogImportExportBinding.inflate(LayoutInflater.from(context)); @@ -1097,7 +166,7 @@ public final class Utils { if (v == importExportBinding.btnSaveTo) { final Editable text = importExportBinding.etPassword.etPassword.getText(); final boolean passwordChecked = importExportBinding.cbPassword.isChecked(); - if (passwordChecked && isEmpty(text)) + if (passwordChecked && TextUtils.isEmpty(text)) Toast.makeText(context, R.string.dialog_export_err_password_empty, Toast.LENGTH_SHORT).show(); else { new DirectoryChooser().setInitialDirectory(folderPath).setInteractionListener(path -> { @@ -1191,132 +260,22 @@ public final class Utils { } } - public static CharSequence getSpannableUrl(final String url) { - if (Utils.isEmpty(url)) return url; - final int httpIndex = url.indexOf("http:"); - final int httpsIndex = url.indexOf("https:"); - if (httpIndex == -1 && httpsIndex == -1) return url; - - final int length = url.length(); - - final int startIndex = httpIndex != -1 ? httpIndex : httpsIndex; - final int spaceIndex = url.indexOf(' ', startIndex + 1); - - final int endIndex = (spaceIndex != -1 ? spaceIndex : length); - - final String extractUrl = url.substring(startIndex, Math.min(length, endIndex)); - - final SpannableString spannableString = new SpannableString(url); - spannableString.setSpan(new URLSpan(extractUrl), startIndex, endIndex, 0); - - return spannableString; - } - - public static boolean isEmpty(final CharSequence charSequence) { - if (charSequence == null || charSequence.length() < 1) return true; - if (charSequence instanceof String) { - String str = (String) charSequence; - if ("".equals(str) || "null".equals(str) || str.isEmpty()) return true; - str = str.trim(); - return "".equals(str) || "null".equals(str) || str.isEmpty(); - } - return "null".contentEquals(charSequence) || "".contentEquals(charSequence) || charSequence.length() < 1; - } - public static boolean isImage(final Uri itemUri, final ContentResolver contentResolver) { String mimeType; if (itemUri == null) return false; final String scheme = itemUri.getScheme(); - if (isEmpty(scheme)) + if (TextUtils.isEmpty(scheme)) mimeType = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(itemUri.toString()).toLowerCase()); else mimeType = scheme.equals(ContentResolver.SCHEME_CONTENT) ? contentResolver.getType(itemUri) : mimeTypeMap.getMimeTypeFromExtension (MimeTypeMap.getFileExtensionFromUrl(itemUri.toString()).toLowerCase()); - if (isEmpty(mimeType)) return true; + if (TextUtils.isEmpty(mimeType)) return true; mimeType = mimeType.toLowerCase(); return mimeType.startsWith("image"); } - @Nullable - public static String getCookie(@Nullable final String webViewUrl) { - int lastLongestCookieLength = 0; - String mainCookie = null; - - String cookie; - if (!Utils.isEmpty(webViewUrl)) { - cookie = Utils.COOKIE_MANAGER.getCookie(webViewUrl); - if (cookie != null) { - final int cookieLen = cookie.length(); - if (cookieLen > lastLongestCookieLength) { - mainCookie = cookie; - lastLongestCookieLength = cookieLen; - } - } - } - cookie = Utils.COOKIE_MANAGER.getCookie("https://instagram.com"); - if (cookie != null) { - final int cookieLen = cookie.length(); - if (cookieLen > lastLongestCookieLength) { - mainCookie = cookie; - lastLongestCookieLength = cookieLen; - } - } - cookie = Utils.COOKIE_MANAGER.getCookie("https://instagram.com/"); - if (cookie != null) { - final int cookieLen = cookie.length(); - if (cookieLen > lastLongestCookieLength) { - mainCookie = cookie; - lastLongestCookieLength = cookieLen; - } - } - cookie = Utils.COOKIE_MANAGER.getCookie("http://instagram.com"); - if (cookie != null) { - final int cookieLen = cookie.length(); - if (cookieLen > lastLongestCookieLength) { - mainCookie = cookie; - lastLongestCookieLength = cookieLen; - } - } - cookie = Utils.COOKIE_MANAGER.getCookie("http://instagram.com/"); - if (cookie != null) { - final int cookieLen = cookie.length(); - if (cookieLen > lastLongestCookieLength) { - mainCookie = cookie; - lastLongestCookieLength = cookieLen; - } - } - cookie = Utils.COOKIE_MANAGER.getCookie("https://www.instagram.com"); - if (cookie != null) { - final int cookieLen = cookie.length(); - if (cookieLen > lastLongestCookieLength) { - mainCookie = cookie; - lastLongestCookieLength = cookieLen; - } - } - cookie = Utils.COOKIE_MANAGER.getCookie("https://www.instagram.com/"); - if (cookie != null) { - final int cookieLen = cookie.length(); - if (cookieLen > lastLongestCookieLength) { - mainCookie = cookie; - lastLongestCookieLength = cookieLen; - } - } - cookie = Utils.COOKIE_MANAGER.getCookie("http://www.instagram.com"); - if (cookie != null) { - final int cookieLen = cookie.length(); - if (cookieLen > lastLongestCookieLength) { - mainCookie = cookie; - lastLongestCookieLength = cookieLen; - } - } - cookie = Utils.COOKIE_MANAGER.getCookie("http://www.instagram.com/"); - if (cookie != null && cookie.length() > lastLongestCookieLength) mainCookie = cookie; - - return mainCookie; - } - public static void errorFinish(@NonNull final Activity activity) { Toast.makeText(activity, R.string.downloader_unknown_error, Toast.LENGTH_SHORT).show(); activity.finish(); @@ -1357,35 +316,6 @@ public final class Utils { return null; } - public static void setConnectionHeaders(final HttpURLConnection connection, final Map headers) { - if (connection == null || headers == null || headers.isEmpty()) { - return; - } - for (Map.Entry header : headers.entrySet()) { - connection.setRequestProperty(header.getKey(), header.getValue()); - } - } - - public static String getQueryString(final Map queryParamsMap) { - if (queryParamsMap == null || queryParamsMap.isEmpty()) { - return ""; - } - final Set> params = queryParamsMap.entrySet(); - final StringBuilder builder = new StringBuilder(); - for (final Map.Entry param : params) { - if (isEmpty(param.getKey())) { - continue; - } - if (builder.length() != 0) { - builder.append("&"); - } - builder.append(param.getKey()); - builder.append("="); - builder.append(param.getValue() != null ? param.getValue() : ""); - } - return builder.toString(); - } - public static SimpleCache getSimpleCacheInstance(final Context context) { if (context == null) { return null; @@ -1393,47 +323,8 @@ public final class Utils { final ExoDatabaseProvider exoDatabaseProvider = new ExoDatabaseProvider(context); final File cacheDir = context.getCacheDir(); if (simpleCache == null && cacheDir != null) { - simpleCache = new SimpleCache(cacheDir, new LeastRecentlyUsedCacheEvictor(MAX_BYTES), exoDatabaseProvider); + simpleCache = new SimpleCache(cacheDir, new LeastRecentlyUsedCacheEvictor(VIDEO_CACHE_MAX_BYTES), exoDatabaseProvider); } return simpleCache; } - - public static int getResultingHeight(final int requiredWidth, final int height, final int width) { - return requiredWidth * height / width; - } - - public static int getResultingWidth(final int requiredHeight, final int height, final int width) { - return requiredHeight * width / height; - } - - public static String getCsrfTokenFromCookie(final String cookie) { - if (cookie == null) { - return null; - } - return cookie.split("csrftoken=")[1].split(";")[0]; - } - - // public static long random(final long lower, final long upper) { - // final long result = lower + new Random().nextLong() * (upper - lower + 1); - // return result; - // } - - public static long random(long origin, long bound) { - final Random random = new Random(); - long r = random.nextLong(); - long n = bound - origin, m = n - 1; - if ((n & m) == 0L) // power of two - r = (r & m) + origin; - else if (n > 0L) { // reject over-represented candidates - for (long u = r >>> 1; // ensure nonnegative - u + m - (r = u % n) < 0L; // rejection check - u = random.nextLong() >>> 1) // retry - ; - r += origin; - } else { // range not representable as long - while (r < origin || r >= bound) - r = random.nextLong(); - } - return r; - } }