mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-18 12:47:30 +00:00
Remove IPTC from downloaded JPG files
This commit is contained in:
parent
09cf333cb0
commit
3ac2ee36aa
@ -31,5 +31,10 @@
|
||||
<option name="name" value="Google" />
|
||||
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven" />
|
||||
<option name="name" value="maven" />
|
||||
<option name="url" value="http://maven.geotoolkit.org/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
@ -51,7 +51,9 @@ dependencies {
|
||||
def nav_version = '2.3.1'
|
||||
|
||||
implementation 'com.google.android.material:material:1.3.0-alpha03'
|
||||
implementation 'com.google.android.exoplayer:exoplayer:2.12.0'
|
||||
|
||||
implementation 'com.google.android.exoplayer:exoplayer-core:2.12.0'
|
||||
implementation 'com.google.android.exoplayer:exoplayer-ui:2.12.0'
|
||||
|
||||
implementation "androidx.appcompat:appcompat:$appcompat_version"
|
||||
implementation "androidx.appcompat:appcompat-resources:$appcompat_version"
|
||||
@ -68,7 +70,6 @@ dependencies {
|
||||
implementation 'com.google.guava:guava:27.0.1-android'
|
||||
|
||||
// implementation 'com.github.hendrawd:StorageUtil:1.1.0'
|
||||
// implementation 'com.github.armcha:AutoLinkTextViewV2:2.1.1'
|
||||
implementation 'com.github.ammargitham:AutoLinkTextViewV2:master-SNAPSHOT'
|
||||
|
||||
implementation 'org.jsoup:jsoup:1.13.1'
|
||||
@ -79,6 +80,9 @@ dependencies {
|
||||
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
|
||||
|
||||
implementation 'com.github.dragon66:icafe:master-SNAPSHOT'
|
||||
implementation 'javax.media:jai_imageio:1.1.1'
|
||||
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.5'
|
||||
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.0'
|
||||
|
@ -5,7 +5,6 @@ import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
@ -37,13 +36,9 @@ 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.FeedModel;
|
||||
import awais.instagrabber.models.PostChild;
|
||||
import awais.instagrabber.models.enums.DownloadMethod;
|
||||
import awais.instagrabber.models.enums.MediaItemType;
|
||||
import awais.instagrabber.workers.DownloadWorker;
|
||||
import awaisomereport.LogCollector;
|
||||
|
||||
@ -63,96 +58,22 @@ public final class DownloadUtils {
|
||||
return lastNotificationId;
|
||||
}
|
||||
|
||||
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) {
|
||||
final File dir = getDownloadDir(context, username);
|
||||
if (dir == null) return;
|
||||
boolean checkEachPost = false;
|
||||
switch (method) {
|
||||
case DOWNLOAD_SAVED:
|
||||
case DOWNLOAD_MAIN:
|
||||
case DOWNLOAD_DISCOVER:
|
||||
checkEachPost = true;
|
||||
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.getShortCode(),
|
||||
isSlider ? "_slide_" + (i + 1) : "",
|
||||
selectedItem.getDisplayUrl()
|
||||
);
|
||||
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) return;
|
||||
final boolean isSlider = result.getItemType() == MediaItemType.MEDIA_TYPE_SLIDER;
|
||||
if (isSlider) {
|
||||
for (int j = 0; j < result.getSliderItems().size(); j++) {
|
||||
final PostChild model = result.getSliderItems().get(j);
|
||||
final File saveFile = getDownloadSaveFile(
|
||||
finalDir,
|
||||
model.getShortCode(),
|
||||
"_slide_" + (j + 1),
|
||||
model.getDisplayUrl()
|
||||
);
|
||||
new DownloadAsync(context,
|
||||
model.getDisplayUrl(),
|
||||
saveFile,
|
||||
file -> {}/*model.setDownloaded(true)*/)
|
||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
} else {
|
||||
final File saveFile = getDownloadSaveFile(
|
||||
finalDir,
|
||||
result.getPostId(),
|
||||
result.getDisplayUrl()
|
||||
);
|
||||
new DownloadAsync(context,
|
||||
result.getDisplayUrl(),
|
||||
saveFile,
|
||||
file -> result.setDownloaded(true))
|
||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static File getDownloadDir(@NonNull final Context context, @Nullable final String username) {
|
||||
@NonNull
|
||||
private static File getDownloadDir() {
|
||||
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 (!TextUtils.isEmpty(customPath)) {
|
||||
dir = new File(customPath);
|
||||
}
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static File getDownloadDir(@NonNull final Context context, @Nullable final String username) {
|
||||
File dir = getDownloadDir();
|
||||
|
||||
if (Utils.settingsHelper.getBoolean(Constants.DOWNLOAD_USER_FOLDER) && !TextUtils.isEmpty(username)) {
|
||||
final String finaleUsername = username.startsWith("@") ? username : "@" + username;
|
||||
@ -216,6 +137,12 @@ public final class DownloadUtils {
|
||||
return new File(finalDir, fileName);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static File getTempFile() {
|
||||
final File dir = getDownloadDir();
|
||||
return new File(dir, UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Copied from {@link MimeTypeMap#getFileExtensionFromUrl(String)})
|
||||
* <p>
|
||||
|
@ -26,9 +26,12 @@ import androidx.work.WorkerParameters;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.icafe4j.image.meta.Metadata;
|
||||
import com.icafe4j.image.meta.MetadataType;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
@ -45,6 +48,7 @@ import awais.instagrabber.BuildConfig;
|
||||
import awais.instagrabber.R;
|
||||
import awais.instagrabber.services.DeleteImageIntentService;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.DownloadUtils;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
import awaisomereport.LogCollector;
|
||||
@ -121,7 +125,9 @@ public class DownloadWorker extends Worker {
|
||||
final int total,
|
||||
final String url,
|
||||
final String filePath) {
|
||||
final File outFile = new File(filePath);
|
||||
final boolean isJpg = filePath.endsWith("jpg");
|
||||
// using temp file approach to remove IPTC so that download progress can be reported
|
||||
final File outFile = isJpg ? DownloadUtils.getTempFile() : new File(filePath);
|
||||
try {
|
||||
final URLConnection urlConnection = new URL(url).openConnection();
|
||||
final long fileSize = Build.VERSION.SDK_INT >= 24 ? urlConnection.getContentLengthLong() :
|
||||
@ -131,44 +137,32 @@ public class DownloadWorker extends Worker {
|
||||
final FileOutputStream fos = new FileOutputStream(outFile)) {
|
||||
final byte[] buffer = new byte[0x2000];
|
||||
int count;
|
||||
boolean deletedIPTC = false;
|
||||
while ((count = bis.read(buffer, 0, 0x2000)) != -1) {
|
||||
totalRead = totalRead + count;
|
||||
// if (!deletedIPTC) {
|
||||
// int iptcStart = -1;
|
||||
// int fbmdStart = -1;
|
||||
// int fbmdBytesLen = -1;
|
||||
// for (int i = 0; i < buffer.length; ++i) {
|
||||
// if (buffer[i] == (byte) 0xFF && buffer[i + 1] == (byte) 0xED)
|
||||
// iptcStart = i;
|
||||
// else if (buffer[i] == (byte) 'F' && buffer[i + 1] == (byte) 'B'
|
||||
// && buffer[i + 2] == (byte) 'M' && buffer[i + 3] == (byte) 'D') {
|
||||
// fbmdStart = i;
|
||||
// fbmdBytesLen = buffer[i - 10] << 24 | (buffer[i - 9] & 0xFF) << 16 |
|
||||
// (buffer[i - 8] & 0xFF) << 8 | (buffer[i - 7] & 0xFF) |
|
||||
// (buffer[i - 6] & 0xFF);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (iptcStart != -1 && fbmdStart != -1 && fbmdBytesLen != -1) {
|
||||
// final int fbmdDataLen = (iptcStart + (fbmdStart - iptcStart) + (fbmdBytesLen - iptcStart)) - 4;
|
||||
// fos.write(buffer, 0, iptcStart);
|
||||
// fos.write(buffer, fbmdDataLen + iptcStart, count - fbmdDataLen - iptcStart);
|
||||
// // setProgressAsync(new Data.Builder().putString(URL, url)
|
||||
// // .putFloat(PROGRESS, totalRead * 100f / fileSize)
|
||||
// // .build());
|
||||
// updateDownloadProgress(notificationId, position, total, totalRead * 100f / fileSize);
|
||||
// deletedIPTC = true;
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
fos.write(buffer, 0, count);
|
||||
// setProgressAsync(new Data.Builder().putString(URL, url)
|
||||
// .putFloat(PROGRESS, totalRead * 100f / fileSize)
|
||||
// .build());
|
||||
setProgressAsync(new Data.Builder().putString(URL, url)
|
||||
.putFloat(PROGRESS, totalRead * 100f / fileSize)
|
||||
.build());
|
||||
updateDownloadProgress(notificationId, position, total, totalRead * 100f / fileSize);
|
||||
}
|
||||
fos.flush();
|
||||
} catch (final Exception e) {
|
||||
Log.e(TAG, "Error while writing data from url: " + url + " to file: " + outFile.getAbsolutePath(), e);
|
||||
}
|
||||
if (isJpg) {
|
||||
final File finalFile = new File(filePath);
|
||||
try (FileInputStream bis = new FileInputStream(outFile);
|
||||
FileOutputStream fos = new FileOutputStream(finalFile)) {
|
||||
Metadata.removeMetadata(bis, fos, MetadataType.IPTC);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error while removing iptc: url: " + url
|
||||
+ ", tempFile: " + outFile.getAbsolutePath()
|
||||
+ ", finalFile: " + finalFile.getAbsolutePath(), e);
|
||||
}
|
||||
final boolean deleted = outFile.delete();
|
||||
if (!deleted) {
|
||||
Log.w(TAG, "download: tempFile not deleted!");
|
||||
}
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
Log.e(TAG, "Error while downloading: " + url, e);
|
||||
@ -176,23 +170,6 @@ public class DownloadWorker extends Worker {
|
||||
updateDownloadProgress(notificationId, position, total, 100);
|
||||
}
|
||||
|
||||
// private void showCompleteNotification(final String url) {
|
||||
// final Context context = getApplicationContext();
|
||||
// final Notification notification = new NotificationCompat.Builder(context, Constants.DOWNLOAD_CHANNEL_ID)
|
||||
// .setCategory(NotificationCompat.CATEGORY_STATUS)
|
||||
// .setSmallIcon(R.drawable.ic_download)
|
||||
// .setAutoCancel(false)
|
||||
// .setOnlyAlertOnce(true)
|
||||
// .setContentTitle(context.getString(R.string.downloader_complete))
|
||||
// .setGroup(DOWNLOAD_GROUP)
|
||||
// .build();
|
||||
// final int id = Math.abs(url.hashCode());
|
||||
// Log.d(TAG, "showCompleteNotification: cancelling: " + id);
|
||||
// notificationManager.cancel(id);
|
||||
// // WorkManager.getInstance(getApplicationContext()).
|
||||
// notificationManager.notify(id + 1, notification);
|
||||
// }
|
||||
|
||||
private void updateDownloadProgress(final int notificationId,
|
||||
final int position,
|
||||
final int total,
|
||||
|
@ -16,6 +16,7 @@ allprojects {
|
||||
google()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
maven { url 'http://maven.geotoolkit.org/' }
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user