Use own message id to relate local and remote messages

This commit is contained in:
M66B 2018-08-06 07:47:46 +00:00
parent b86f70bccb
commit d3a235e2d0
3 changed files with 98 additions and 26 deletions

View File

@ -82,8 +82,8 @@ public class MessageHelper {
return props;
}
static MimeMessage from(EntityMessage message, Session isession) throws MessagingException {
MimeMessage imessage = new MimeMessage(isession);
static MimeMessageEx from(EntityMessage message, Session isession) throws MessagingException {
MimeMessageEx imessage = new MimeMessageEx(isession, message.id);
if (message.from != null) {
Address[] from = MessageHelper.decodeAddresses(message.from);
@ -111,8 +111,8 @@ public class MessageHelper {
return imessage;
}
static MimeMessage from(EntityMessage message, EntityMessage reply, Session isession) throws MessagingException {
MimeMessage imessage = from(message, isession);
static MimeMessageEx from(EntityMessage message, EntityMessage reply, Session isession) throws MessagingException {
MimeMessageEx imessage = from(message, isession);
imessage.addHeader("In-Reply-To", reply.msgid);
imessage.addHeader("References", (reply.references == null ? "" : reply.references + " ") + reply.msgid);
return imessage;

View File

@ -0,0 +1,64 @@
package eu.faircode.email;
import android.text.TextUtils;
import android.util.Log;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
public class MimeMessageEx extends MimeMessage {
private long id = -1;
public MimeMessageEx(Session session, long id) {
super(session);
this.id = id;
}
@Override
protected void updateMessageID() throws MessagingException {
try {
StringBuffer sb = new StringBuffer();
sb.append('<')
.append(id).append('.')
.append(BuildConfig.APPLICATION_ID).append('.')
.append(System.currentTimeMillis()).append('.')
.append("anonymous@localhost")
.append('>');
setHeader("Message-ID", sb.toString());
Log.i(Helper.TAG, "Override Message-ID=" + sb.toString());
} catch (Throwable ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
super.updateMessageID();
}
}
public static long getId(MimeMessage message) {
try {
String msgid = message.getMessageID();
if (msgid == null)
return -1;
List<String> parts = new ArrayList<>(Arrays.asList(msgid.split("\\.")));
if (parts.size() < 1)
return -1;
String part = parts.get(0);
parts.remove(0);
if (!TextUtils.join(".", parts).startsWith(BuildConfig.APPLICATION_ID))
return -1;
long id = Long.parseLong(part.substring(1));
Log.i(Helper.TAG, "Parsed Message-ID=" + msgid + " id=" + id);
return id;
} catch (Throwable ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
return -1;
}
}
}

View File

@ -711,18 +711,13 @@ public class ServiceSynchronize extends LifecycleService {
ifolder.appendMessages(new Message[]{imessage});
// Drafts can be appended multiple times
try {
if (msg.uid != null) {
Message previously = ifolder.getMessageByUID(msg.uid);
if (previously == null)
throw new MessageRemovedException();
if (msg.uid != null) {
Message previously = ifolder.getMessageByUID(msg.uid);
if (previously == null)
throw new MessageRemovedException();
previously.setFlag(Flags.Flag.DELETED, true);
ifolder.expunge();
}
} finally {
// Remote will report appended
message.deleteMessage(op.message);
previously.setFlag(Flags.Flag.DELETED, true);
ifolder.expunge();
}
} else if (EntityOperation.MOVE.equals(op.name)) {
@ -789,7 +784,9 @@ public class ServiceSynchronize extends LifecycleService {
Log.i(Helper.TAG, "Sent via " + ident.host + "/" + ident.user +
" to " + TextUtils.join(", ", to));
message.deleteMessage(op.message);
msg.ui_hide = true;
message.updateMessage(msg);
// TODO: purge sent messages
} finally {
itransport.close();
}
@ -1002,13 +999,14 @@ public class ServiceSynchronize extends LifecycleService {
}
private void synchronizeMessage(EntityFolder folder, IMAPFolder ifolder, IMAPMessage imessage) throws MessagingException, JSONException, IOException {
FetchProfile fp = new FetchProfile();
fp.add(UIDFolder.FetchProfileItem.UID);
fp.add(IMAPFolder.FetchProfileItem.FLAGS);
ifolder.fetch(new Message[]{imessage}, fp);
long uid = ifolder.getUID(imessage);
long uid = -1;
try {
FetchProfile fp = new FetchProfile();
fp.add(UIDFolder.FetchProfileItem.UID);
fp.add(IMAPFolder.FetchProfileItem.FLAGS);
ifolder.fetch(new Message[]{imessage}, fp);
uid = ifolder.getUID(imessage);
Log.i(Helper.TAG, folder.name + " start sync uid=" + uid);
if (imessage.isExpunged()) {
@ -1033,7 +1031,12 @@ public class ServiceSynchronize extends LifecycleService {
fp1.add(IMAPFolder.FetchProfileItem.MESSAGE);
ifolder.fetch(new Message[]{imessage}, fp1);
message = new EntityMessage();
long id = MimeMessageEx.getId(imessage);
message = db.message().getMessage(id);
boolean update = (message != null);
if (message == null)
message = new EntityMessage();
message.account = folder.account;
message.folder = folder.id;
message.uid = uid;
@ -1054,8 +1057,13 @@ public class ServiceSynchronize extends LifecycleService {
message.ui_seen = seen;
message.ui_hide = false;
message.id = db.message().insertMessage(message);
Log.i(Helper.TAG, folder.name + " added id=" + message.id);
if (update) {
db.message().updateMessage(message);
Log.i(Helper.TAG, folder.name + " updated id=" + message.id);
} else {
message.id = db.message().insertMessage(message);
Log.i(Helper.TAG, folder.name + " added id=" + message.id);
}
int sequence = 0;
for (EntityAttachment attachment : helper.getAttachments()) {
@ -1066,7 +1074,6 @@ public class ServiceSynchronize extends LifecycleService {
attachment.sequence = sequence;
attachment.id = db.attachment().insertAttachment(attachment);
}
} else if (message.seen != seen) {
message.seen = seen;
message.ui_seen = seen;
@ -1074,6 +1081,7 @@ public class ServiceSynchronize extends LifecycleService {
db.message().updateMessage(message);
Log.i(Helper.TAG, folder.name + " updated id=" + message.id);
}
} finally {
Log.i(Helper.TAG, folder.name + " end sync uid=" + uid);
}