Move raw message cross account

This commit is contained in:
M66B 2019-01-25 12:45:37 +00:00
parent 0fca2da4e2
commit 892e2757c3
4 changed files with 105 additions and 57 deletions

View File

@ -178,15 +178,23 @@ public class EntityOperation {
db.message().countMessageByMsgId(target.id, message.msgid) == 0) {
long id = message.id;
long uid = message.uid;
boolean seen = message.seen;
boolean ui_seen = message.ui_seen;
message.id = null;
message.account = target.account;
message.folder = target.id;
message.uid = null;
if (autoread) {
message.seen = true;
message.ui_seen = true;
}
newid = db.message().insertMessage(message);
message.id = id;
message.account = source.account;
message.folder = source.id;
message.uid = uid;
message.seen = seen;
message.ui_seen = ui_seen;
if (message.content)
try {
@ -205,13 +213,20 @@ public class EntityOperation {
}
// Cross account move
if (!source.account.equals(target.account)) {
name = ADD;
folder = target.id;
jargs = new JSONArray();
jargs.put(0, newid); // Can be null
jargs.put(1, autoread);
}
if (!source.account.equals(target.account))
if (message.raw != null && message.raw) {
name = ADD;
folder = target.id;
jargs = new JSONArray();
jargs.put(0, newid); // Can be null
jargs.put(1, autoread);
} else {
name = RAW;
jargs = new JSONArray();
jargs.put(0, newid); // Can be null
jargs.put(1, autoread);
jargs.put(2, target.id);
}
} else if (DELETE.equals(name))
db.message().setMessageUiHide(message.id, true);

View File

@ -2107,18 +2107,6 @@ public class FragmentMessages extends FragmentBase {
EntityMessage message = db.message().getMessage(target.id);
if (message != null) {
Log.i("Move id=" + target.id + " target=" + target.folder.name);
// Cross account move: check if message downloaded
if (!target.folder.account.equals(message.account)) {
if (!message.content)
throw new IllegalArgumentException(getString(R.string.title_no_accross));
List<EntityAttachment> attachments = db.attachment().getAttachments(message.id);
for (EntityAttachment attachment : attachments)
if (!attachment.available)
throw new IllegalArgumentException(getString(R.string.title_no_accross));
}
EntityOperation.queue(context, db, message, EntityOperation.MOVE, target.folder.id);
}
}

View File

@ -61,10 +61,13 @@ import com.sun.mail.util.MailConnectException;
import org.json.JSONArray;
import org.json.JSONException;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.net.SocketTimeoutException;
@ -1496,7 +1499,7 @@ public class ServiceSynchronize extends LifecycleService {
doHeaders(folder, ifolder, message, db);
else if (EntityOperation.RAW.equals(op.name))
doRaw(folder, ifolder, message, db);
doRaw(folder, ifolder, message, jargs, db);
else if (EntityOperation.BODY.equals(op.name))
doBody(folder, ifolder, message, db);
@ -1537,19 +1540,27 @@ public class ServiceSynchronize extends LifecycleService {
db.operation().deleteOperation(op.id);
// Cleanup
if (message != null)
if (ex instanceof MessageRemovedException) {
if (message != null) {
if (ex instanceof MessageRemovedException)
db.message().deleteMessage(message.id);
// Delete temporary copy in target folder
if (EntityOperation.MOVE.equals(op.name) &&
jargs.length() > 2)
db.message().deleteMessage(jargs.getInt(2));
if (EntityOperation.ADD.equals(op.name) &&
jargs.length() > 0 && !jargs.isNull(0))
db.message().deleteMessage(jargs.getInt(0));
} else
Long newid = null;
if (EntityOperation.MOVE.equals(op.name) &&
jargs.length() > 2)
newid = jargs.getLong(2);
if ((EntityOperation.ADD.equals(op.name) ||
EntityOperation.RAW.equals(op.name)) &&
jargs.length() > 0 && !jargs.isNull(0))
newid = jargs.getLong(0);
// Delete temporary copy in target folder
if (newid != null) {
db.message().deleteMessage(newid);
db.message().setMessageUiHide(message.id, false);
}
}
continue;
} else if (ex instanceof MessagingException) {
@ -1673,21 +1684,41 @@ public class ServiceSynchronize extends LifecycleService {
}
private void doAdd(EntityFolder folder, Session isession, IMAPFolder ifolder, EntityMessage message, JSONArray jargs, DB db) throws MessagingException, JSONException, IOException {
if (!message.content)
throw new IllegalArgumentException("Message body missing");
MimeMessage imessage;
if (folder.id.equals(message.folder)) {
if (!message.content)
throw new IllegalArgumentException("Message body missing");
List<EntityAttachment> attachments = db.attachment().getAttachments(message.id);
for (EntityAttachment attachment : attachments)
if (!attachment.available)
throw new IllegalArgumentException("Attachment missing");
List<EntityAttachment> attachments = db.attachment().getAttachments(message.id);
for (EntityAttachment attachment : attachments)
if (!attachment.available)
throw new IllegalArgumentException("Attachment missing");
// Append message
MimeMessage imessage = MessageHelper.from(this, message, isession);
imessage = MessageHelper.from(this, message, isession);
} else {
// Cross account move
File file = EntityMessage.getRawFile(this, message.id);
if (!file.exists())
throw new IllegalArgumentException("raw message file not found");
InputStream is = null;
try {
Log.i(folder.name + " reading " + file);
is = new BufferedInputStream(new FileInputStream(file));
imessage = new MimeMessage(isession, is);
} finally {
if (is != null)
is.close();
}
}
boolean autoread = false;
if (jargs.length() > 1) {
boolean autoread = jargs.getBoolean(1);
if (autoread && !imessage.isSet(Flags.Flag.SEEN))
autoread = jargs.getBoolean(1);
if (autoread && !imessage.isSet(Flags.Flag.SEEN)) {
Log.i(folder.name + " autoread");
imessage.setFlag(Flags.Flag.SEEN, true);
}
}
if (EntityFolder.DRAFTS.equals(folder.type)) {
@ -1698,8 +1729,15 @@ public class ServiceSynchronize extends LifecycleService {
ifolder.appendMessages(new Message[]{imessage});
// Cross account move
if (!folder.id.equals(message.folder))
if (!folder.id.equals(message.folder)) {
if (autoread) {
Log.i(folder.name + " queuing SEEN id=" + message.id);
EntityOperation.queue(this, db, message, EntityOperation.SEEN, true);
}
Log.i(folder.name + " queuing DELETE id=" + message.id);
EntityOperation.queue(this, db, message, EntityOperation.DELETE);
}
}
private void doMove(EntityFolder folder, Session isession, IMAPStore istore, IMAPFolder ifolder, EntityMessage message, JSONArray jargs, DB db) throws JSONException, MessagingException, IOException {
@ -1740,7 +1778,7 @@ public class ServiceSynchronize extends LifecycleService {
}
}
private void doDelete(EntityFolder folder, IMAPFolder ifolder, EntityMessage message, JSONArray jargs, DB db) throws MessagingException, JSONException {
private void doDelete(EntityFolder folder, IMAPFolder ifolder, EntityMessage message, JSONArray jargs, DB db) throws MessagingException {
// Delete message
if (message.msgid != null) {
Message[] imessages = ifolder.search(new MessageIDTerm(message.msgid));
@ -1953,7 +1991,7 @@ public class ServiceSynchronize extends LifecycleService {
}
}
private void doHeaders(EntityFolder folder, IMAPFolder ifolder, EntityMessage message, DB db) throws MessagingException, IOException {
private void doHeaders(EntityFolder folder, IMAPFolder ifolder, EntityMessage message, DB db) throws MessagingException {
if (message.headers != null)
return;
@ -1965,29 +2003,37 @@ public class ServiceSynchronize extends LifecycleService {
db.message().setMessageHeaders(message.id, helper.getHeaders());
}
private void doRaw(EntityFolder folder, IMAPFolder ifolder, EntityMessage message, DB db) throws MessagingException, IOException {
if (message.raw)
return;
Message imessage = ifolder.getMessageByUID(message.uid);
if (imessage == null)
throw new MessageRemovedException();
if (imessage instanceof MimeMessage) {
MimeMessage mmessage = (MimeMessage) imessage;
private void doRaw(EntityFolder folder, IMAPFolder ifolder, EntityMessage message, JSONArray jargs, DB db) throws MessagingException, IOException, JSONException {
if (message.raw == null || !message.raw) {
IMAPMessage imessage = (IMAPMessage) ifolder.getMessageByUID(message.uid);
if (imessage == null)
throw new MessageRemovedException();
File file = EntityMessage.getRawFile(this, message.id);
OutputStream os = null;
try {
os = new BufferedOutputStream(new FileOutputStream(file));
mmessage.writeTo(os);
imessage.writeTo(os);
db.message().setMessageRaw(message.id, true);
} finally {
if (os != null)
os.close();
}
}
db.message().setMessageRaw(message.id, true);
if (jargs.length() > 0) {
long target = jargs.getLong(2);
jargs.remove(2);
Log.i(folder.name + " queuing ADD id=" + message.id + ":" + target);
EntityOperation operation = new EntityOperation();
operation.folder = target;
operation.message = message.id;
operation.name = EntityOperation.ADD;
operation.args = jargs.toString();
operation.created = new Date().getTime();
operation.id = db.operation().insertOperation(operation);
}
}

View File

@ -306,8 +306,7 @@
<string name="title_no_stream">An outdated app sent a file path instead of a file stream</string>
<string name="title_no_contacts">Contact picker not available</string>
<string name="title_no_internet">No internet connection</string>
<string name="title_no_accross">Moving across accounts requires all message content to be downloaded</string>
<string name="title_accross_remark">Messages moved across accounts will not be identical after moving</string>
<string name="title_accross_remark">Messages moved across accounts will be downloaded again causing and extra data usage</string>
<string name="title_raw_saved">Raw message saved</string>
<string name="title_attachment_saved">Attachment saved</string>
<string name="title_attachments_saved">Attachments saved</string>