diff --git a/app/src/main/java/eu/faircode/email/ActivityView.java b/app/src/main/java/eu/faircode/email/ActivityView.java index 28b311522e..b847056678 100644 --- a/app/src/main/java/eu/faircode/email/ActivityView.java +++ b/app/src/main/java/eu/faircode/email/ActivityView.java @@ -1350,20 +1350,21 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB Helper.writeText(m.getFile(context), parts.getHtml(context)); // Remove previously decrypted attachments - for (EntityAttachment a : attachments) - if (a.encryption == null) - db.attachment().deleteAttachment(a.id); + for (EntityAttachment local : attachments) + if (local.encryption == null) + db.attachment().deleteAttachment(local.id); - // Add decrypted attachments - attachments = parts.getAttachments(); int sequence = db.attachment().getAttachmentSequence(id); - for (int index = 0; index < attachments.size(); index++) { - EntityAttachment a = attachments.get(index); - a.message = id; - a.sequence = ++sequence; - a.id = db.attachment().insertAttachment(a); + + // Add decrypted attachments + List remotes = parts.getAttachments(); + for (int index = 0; index < remotes.size(); index++) { + EntityAttachment remote = remotes.get(index); + remote.message = id; + remote.sequence = ++sequence; + remote.id = db.attachment().insertAttachment(remote); try { - parts.downloadAttachment(context, a); + parts.downloadAttachment(context, index, remote.id, remote.name); } catch (Throwable ex) { Log.e(ex); } diff --git a/app/src/main/java/eu/faircode/email/Core.java b/app/src/main/java/eu/faircode/email/Core.java index e2164a58fc..db83769a6e 100644 --- a/app/src/main/java/eu/faircode/email/Core.java +++ b/app/src/main/java/eu/faircode/email/Core.java @@ -707,12 +707,12 @@ class Core { long id = jargs.getLong(0); // Get attachment - EntityAttachment attachment = db.attachment().getAttachment(id); - if (attachment == null) - attachment = db.attachment().getAttachment(message.id, (int) id); // legacy - if (attachment == null) + EntityAttachment local = db.attachment().getAttachment(id); + if (local == null) + local = db.attachment().getAttachment(message.id, (int) id); // legacy + if (local == null) throw new IllegalArgumentException("Attachment not found"); - if (attachment.available) + if (local.available) return; // Get message @@ -720,28 +720,32 @@ class Core { if (imessage == null) throw new MessageRemovedException(); + // Get message parts + MessageHelper helper = new MessageHelper((MimeMessage) imessage); + MessageHelper.MessageParts parts = helper.getMessageParts(); + // Match attachment by attributes // Some servers order attachments randomly boolean found = false; - List attachments = db.attachment().getAttachments(message.id); - for (EntityAttachment a : attachments) { - if (Objects.equals(a.name, attachment.name) && - Objects.equals(a.type, attachment.type) && - Objects.equals(a.disposition, attachment.disposition) && - Objects.equals(a.cid, attachment.cid) && - Objects.equals(a.encryption, attachment.encryption) && - Objects.equals(a.size, attachment.size)) { + List remotes = parts.getAttachments(); + for (int i = 0; i < remotes.size(); i++) { + EntityAttachment remote = remotes.get(i); + if (Objects.equals(remote.name, local.name) && + Objects.equals(remote.type, local.type) && + Objects.equals(remote.disposition, local.disposition) && + Objects.equals(remote.cid, local.cid) && + Objects.equals(remote.encryption, local.encryption) && + Objects.equals(remote.size, local.size)) { found = true; - - // Download attachment - MessageHelper helper = new MessageHelper((MimeMessage) imessage); - MessageHelper.MessageParts parts = helper.getMessageParts(); - parts.downloadAttachment(context, a); + parts.downloadAttachment(context, i, local.id, local.name); } } - if (!found && !EntityFolder.DRAFTS.equals(folder.type)) - throw new IllegalArgumentException("Attachment not found"); + if (!found) { + db.attachment().setError(local.id, "Attachment not found"); + if (!EntityFolder.DRAFTS.equals(folder.type)) + throw new IllegalArgumentException("Attachment not found"); + } updateMessageSize(context, message.id); } @@ -1597,11 +1601,22 @@ class Core { } } - for (EntityAttachment attachment : attachments) - if (!attachment.available) - if (state.getNetworkState().isUnmetered() || (attachment.size != null && attachment.size < maxSize)) + List remotes = parts.getAttachments(); + + for (EntityAttachment local : attachments) + if (!local.available) + if (state.getNetworkState().isUnmetered() || (local.size != null && local.size < maxSize)) try { - parts.downloadAttachment(context, attachment); + for (int i = 0; i < remotes.size(); i++) { + EntityAttachment remote = remotes.get(i); + if (Objects.equals(remote.name, local.name) && + Objects.equals(remote.type, local.type) && + Objects.equals(remote.disposition, local.disposition) && + Objects.equals(remote.cid, local.cid) && + Objects.equals(remote.encryption, local.encryption) && + Objects.equals(remote.size, local.size)) + parts.downloadAttachment(context, i, local.id, local.name); + } } catch (Throwable ex) { Log.e(ex); } diff --git a/app/src/main/java/eu/faircode/email/EntityAttachment.java b/app/src/main/java/eu/faircode/email/EntityAttachment.java index ebff2f428c..bc742a75a0 100644 --- a/app/src/main/java/eu/faircode/email/EntityAttachment.java +++ b/app/src/main/java/eu/faircode/email/EntityAttachment.java @@ -81,6 +81,10 @@ public class EntityAttachment { } File getFile(Context context) { + return getFile(context, id, name); + } + + static File getFile(Context context, long id, String name) { File dir = new File(context.getFilesDir(), "attachments"); if (!dir.exists()) dir.mkdir(); @@ -130,4 +134,10 @@ public class EntityAttachment { } else return false; } + + @NonNull + @Override + public String toString() { + return (this.name + " type=" + this.type + " disposition=" + this.disposition + " cid=" + this.cid + " size=" + this.size); + } } diff --git a/app/src/main/java/eu/faircode/email/MessageHelper.java b/app/src/main/java/eu/faircode/email/MessageHelper.java index 6bddcc25fe..a3cb1dbd40 100644 --- a/app/src/main/java/eu/faircode/email/MessageHelper.java +++ b/app/src/main/java/eu/faircode/email/MessageHelper.java @@ -848,17 +848,17 @@ public class MessageHelper { return result; } - void downloadAttachment(Context context, EntityAttachment attachment) throws MessagingException, IOException { - Log.i("downloading attachment id=" + attachment.id); + void downloadAttachment(Context context, int index, long id, String name) throws MessagingException, IOException { + Log.i("downloading attachment id=" + id); DB db = DB.getInstance(context); // Get data - AttachmentPart apart = attachments.get(attachment.sequence - 1); + AttachmentPart apart = attachments.get(index); // Download attachment - File file = attachment.getFile(context); - db.attachment().setProgress(attachment.id, null); + File file = EntityAttachment.getFile(context, id, name); + db.attachment().setProgress(id, null); try (InputStream is = apart.part.getInputStream()) { long size = 0; long total = apart.part.getSize(); @@ -871,19 +871,19 @@ public class MessageHelper { // Update progress if (total > 0) - db.attachment().setProgress(attachment.id, (int) (size * 100 / total)); + db.attachment().setProgress(id, (int) (size * 100 / total)); } } // Store attachment data - db.attachment().setDownloaded(attachment.id, size); + db.attachment().setDownloaded(id, size); Log.i("Downloaded attachment size=" + size); } catch (FolderClosedIOException ex) { throw new FolderClosedException(ex.getFolder(), "downloadAttachment", ex); } catch (Throwable ex) { // Reset progress on failure - db.attachment().setError(attachment.id, Helper.formatThrowable(ex)); + db.attachment().setError(id, Helper.formatThrowable(ex)); throw ex; } }