BarInsta/app/src/main/java/awais/instagrabber/utils/DownloadUtils.java

219 lines
10 KiB
Java
Raw Normal View History

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<? extends BasePostModel> 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<? extends BasePostModel> 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);
}
}