mirror of https://github.com/M66B/FairEmail.git
Match attachments by properties
This commit is contained in:
parent
61f7a2f692
commit
4cf330dfb6
File diff suppressed because it is too large
Load Diff
|
@ -1390,7 +1390,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
|
|||
a.sequence = ++sequence;
|
||||
a.id = db.attachment().insertAttachment(a);
|
||||
try {
|
||||
parts.downloadAttachment(context, index, a.id);
|
||||
parts.downloadAttachment(context, a);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
|
|
|
@ -248,7 +248,7 @@ public class AdapterAttachment extends RecyclerView.Adapter<AdapterAttachment.Vi
|
|||
|
||||
db.attachment().setProgress(id, 0);
|
||||
|
||||
EntityOperation.queue(context, db, message, EntityOperation.ATTACHMENT, sequence);
|
||||
EntityOperation.queue(context, db, message, EntityOperation.ATTACHMENT, id);
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
|
|
|
@ -150,7 +150,7 @@ public class AdapterImage extends RecyclerView.Adapter<AdapterImage.ViewHolder>
|
|||
db.attachment().setProgress(id, 0);
|
||||
|
||||
EntityMessage msg = db.message().getMessage(message);
|
||||
EntityOperation.queue(context, db, msg, EntityOperation.ATTACHMENT, sequence);
|
||||
EntityOperation.queue(context, db, msg, EntityOperation.ATTACHMENT, id);
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
|
|
|
@ -1343,7 +1343,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
|
|||
for (EntityAttachment attachment : db.attachment().getAttachments(message.id))
|
||||
if (attachment.progress == null && !attachment.available) {
|
||||
db.attachment().setProgress(attachment.id, 0);
|
||||
EntityOperation.queue(context, db, msg, EntityOperation.ATTACHMENT, attachment.sequence);
|
||||
EntityOperation.queue(context, db, msg, EntityOperation.ATTACHMENT, attachment.id);
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
|
@ -1691,7 +1691,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
|
|||
List<EntityAttachment> attachments = db.attachment().getAttachments(message.id);
|
||||
for (EntityAttachment attachment : attachments)
|
||||
if (!attachment.available && !TextUtils.isEmpty(attachment.cid))
|
||||
EntityOperation.queue(context, db, message, EntityOperation.ATTACHMENT, attachment.sequence);
|
||||
EntityOperation.queue(context, db, message, EntityOperation.ATTACHMENT, attachment.id);
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
|
|
|
@ -691,10 +691,14 @@ class Core {
|
|||
// Download attachment
|
||||
DB db = DB.getInstance(context);
|
||||
|
||||
int sequence = jargs.getInt(0);
|
||||
long id = jargs.getLong(0);
|
||||
|
||||
// Get attachment
|
||||
EntityAttachment attachment = db.attachment().getAttachment(op.message, sequence);
|
||||
EntityAttachment attachment = db.attachment().getAttachment(id);
|
||||
if (attachment == null)
|
||||
attachment = db.attachment().getAttachment(message.id, (int) id); // legacy
|
||||
if (attachment == null)
|
||||
throw new IllegalArgumentException("Attachment not found");
|
||||
if (attachment.available)
|
||||
return;
|
||||
|
||||
|
@ -703,10 +707,28 @@ class Core {
|
|||
if (imessage == null)
|
||||
throw new MessageRemovedException();
|
||||
|
||||
// Download attachment
|
||||
MessageHelper helper = new MessageHelper((MimeMessage) imessage);
|
||||
MessageHelper.MessageParts parts = helper.getMessageParts();
|
||||
parts.downloadAttachment(context, sequence - 1, attachment.id);
|
||||
// Match attachment by attributes
|
||||
// Some servers order attachments randomly
|
||||
boolean found = false;
|
||||
List<EntityAttachment> 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)) {
|
||||
found = true;
|
||||
|
||||
// Download attachment
|
||||
MessageHelper helper = new MessageHelper((MimeMessage) imessage);
|
||||
MessageHelper.MessageParts parts = helper.getMessageParts();
|
||||
parts.downloadAttachment(context, a);
|
||||
}
|
||||
}
|
||||
|
||||
if (!found && !EntityFolder.DRAFTS.equals(folder.type))
|
||||
throw new IllegalArgumentException("Attachment not found");
|
||||
|
||||
updateMessageSize(context, message.id);
|
||||
}
|
||||
|
@ -1566,7 +1588,7 @@ class Core {
|
|||
if (!attachment.available)
|
||||
if (state.getNetworkState().isUnmetered() || (attachment.size != null && attachment.size < maxSize))
|
||||
try {
|
||||
parts.downloadAttachment(context, attachment.sequence - 1, attachment.id);
|
||||
parts.downloadAttachment(context, attachment);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory;
|
|||
// https://developer.android.com/topic/libraries/architecture/room.html
|
||||
|
||||
@Database(
|
||||
version = 79,
|
||||
version = 80,
|
||||
entities = {
|
||||
EntityIdentity.class,
|
||||
EntityAccount.class,
|
||||
|
@ -801,6 +801,14 @@ public abstract class DB extends RoomDatabase {
|
|||
db.execSQL("ALTER TABLE `message` ADD COLUMN `plain_only` INTEGER");
|
||||
}
|
||||
})
|
||||
.addMigrations(new Migration(79, 80) {
|
||||
@Override
|
||||
public void migrate(SupportSQLiteDatabase db) {
|
||||
Log.i("DB migration from version " + startVersion + " to " + endVersion);
|
||||
db.execSQL("DROP INDEX index_attachment_message_cid");
|
||||
db.execSQL("CREATE INDEX `index_attachment_message_cid` ON `attachment` (`message`, `cid`)");
|
||||
}
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,8 @@ public interface DaoAttachment {
|
|||
|
||||
@Query("SELECT * FROM attachment" +
|
||||
" WHERE message = :message" +
|
||||
" AND cid = :cid")
|
||||
" AND cid = :cid" +
|
||||
" LIMIT 1")
|
||||
EntityAttachment getAttachment(long message, String cid);
|
||||
|
||||
@Query("UPDATE attachment" +
|
||||
|
@ -67,11 +68,6 @@ public interface DaoAttachment {
|
|||
" WHERE id = :id")
|
||||
void setMessage(long id, long message);
|
||||
|
||||
@Query("UPDATE attachment" +
|
||||
" SET name = :name, type = :type, disposition = :disposition, cid = :cid, encryption = :encryption" +
|
||||
" WHERE id = :id")
|
||||
void setInfo(long id, String name, String type, String disposition, String cid, Integer encryption);
|
||||
|
||||
@Query("UPDATE attachment" +
|
||||
" SET error = NULL, progress = :progress, available = 0" +
|
||||
" WHERE id = :id")
|
||||
|
|
|
@ -45,7 +45,7 @@ import static androidx.room.ForeignKey.CASCADE;
|
|||
indices = {
|
||||
@Index(value = {"message"}),
|
||||
@Index(value = {"message", "sequence"}, unique = true),
|
||||
@Index(value = {"message", "cid"}, unique = true)
|
||||
@Index(value = {"message", "cid"})
|
||||
}
|
||||
)
|
||||
public class EntityAttachment {
|
||||
|
|
|
@ -2182,7 +2182,7 @@ public class FragmentCompose extends FragmentBase {
|
|||
List<EntityAttachment> attachments = db.attachment().getAttachments(draft.id);
|
||||
for (EntityAttachment attachment : attachments)
|
||||
if (!attachment.available)
|
||||
EntityOperation.queue(context, db, draft, EntityOperation.ATTACHMENT, attachment.sequence);
|
||||
EntityOperation.queue(context, db, draft, EntityOperation.ATTACHMENT, attachment.id);
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
|
|
|
@ -826,34 +826,17 @@ public class MessageHelper {
|
|||
return result;
|
||||
}
|
||||
|
||||
void downloadAttachment(Context context, int index, long id) throws MessagingException, IOException {
|
||||
Log.i("downloading attchment id=" + id + " seq=" + index);
|
||||
|
||||
// Attachments of drafts might not have been uploaded yet
|
||||
if (index >= attachments.size()) {
|
||||
Log.w("Attachment unavailable sequence=" + index + " size=" + attachments.size());
|
||||
return;
|
||||
}
|
||||
void downloadAttachment(Context context, EntityAttachment attachment) throws MessagingException, IOException {
|
||||
Log.i("downloading attachment id=" + attachment.id);
|
||||
|
||||
DB db = DB.getInstance(context);
|
||||
|
||||
// Get data
|
||||
AttachmentPart apart = attachments.get(index);
|
||||
EntityAttachment attachment = db.attachment().getAttachment(id);
|
||||
if (attachment == null)
|
||||
return;
|
||||
|
||||
// Set info again in case ordering changed
|
||||
db.attachment().setInfo(id,
|
||||
apart.attachment.name,
|
||||
apart.attachment.type,
|
||||
apart.attachment.disposition,
|
||||
apart.attachment.cid,
|
||||
apart.attachment.encryption);
|
||||
AttachmentPart apart = attachments.get(attachment.sequence - 1);
|
||||
|
||||
// Download attachment
|
||||
File file = attachment.getFile(context);
|
||||
db.attachment().setProgress(id, null);
|
||||
db.attachment().setProgress(attachment.id, null);
|
||||
try (InputStream is = apart.part.getInputStream()) {
|
||||
long size = 0;
|
||||
long total = apart.part.getSize();
|
||||
|
@ -866,19 +849,19 @@ public class MessageHelper {
|
|||
|
||||
// Update progress
|
||||
if (total > 0)
|
||||
db.attachment().setProgress(id, (int) (size * 100 / total));
|
||||
db.attachment().setProgress(attachment.id, (int) (size * 100 / total));
|
||||
}
|
||||
}
|
||||
|
||||
// Store attachment data
|
||||
db.attachment().setDownloaded(id, size);
|
||||
db.attachment().setDownloaded(attachment.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(id, Helper.formatThrowable(ex));
|
||||
db.attachment().setError(attachment.id, Helper.formatThrowable(ex));
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
@ -922,18 +905,6 @@ public class MessageHelper {
|
|||
|
||||
getMessageParts(cmessage, parts, false);
|
||||
|
||||
// Fix duplicate CIDs
|
||||
List<EntityAttachment> attachments = parts.getAttachments();
|
||||
for (int i = 0; i < attachments.size(); i++) {
|
||||
String cid = attachments.get(i).cid;
|
||||
if (cid != null)
|
||||
for (int j = i + 1; j < attachments.size(); j++) {
|
||||
EntityAttachment a = attachments.get(j);
|
||||
if (cid.equals(a.cid))
|
||||
a.cid = null;
|
||||
}
|
||||
}
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue