Added POP3 batch delete

pull/209/head
M66B 3 years ago
parent 89e4afd724
commit 17f7e16651

@ -300,6 +300,17 @@ class Core {
similar.put(next, m); similar.put(next, m);
} }
} }
if (group &&
op.name.equals(next.name) &&
account.protocol == EntityAccount.TYPE_POP) {
JSONArray jnext = new JSONArray(next.args);
// Same target
if (jargs.getLong(0) == jnext.getLong(0)) {
EntityMessage m = db.message().getMessage(next.message);
if (m != null)
similar.put(next, m);
}
}
break; break;
case EntityOperation.DELETE: case EntityOperation.DELETE:
@ -312,6 +323,13 @@ class Core {
m.uid != null && m.ui_deleted == message.ui_deleted) m.uid != null && m.ui_deleted == message.ui_deleted)
similar.put(next, m); similar.put(next, m);
} }
if (group &&
op.name.equals(next.name) &&
account.protocol == EntityAccount.TYPE_POP) {
EntityMessage m = db.message().getMessage(next.message);
if (m != null)
similar.put(next, m);
}
break; break;
} }
@ -367,7 +385,11 @@ class Core {
db.endTransaction(); db.endTransaction();
} }
if (istore instanceof POP3Store) if (istore instanceof POP3Store) {
List<EntityMessage> messages = new ArrayList<>();
messages.add(message);
messages.addAll(similar.values());
switch (op.name) { switch (op.name) {
case EntityOperation.SEEN: case EntityOperation.SEEN:
onSeen(context, jargs, folder, message, (POP3Folder) ifolder); onSeen(context, jargs, folder, message, (POP3Folder) ifolder);
@ -388,11 +410,11 @@ class Core {
break; break;
case EntityOperation.MOVE: case EntityOperation.MOVE:
onMove(context, jargs, account, folder, message, (POP3Folder) ifolder, (POP3Store) istore, state); onMove(context, jargs, account, folder, messages, (POP3Folder) ifolder, (POP3Store) istore, state);
break; break;
case EntityOperation.DELETE: case EntityOperation.DELETE:
onDelete(context, jargs, account, folder, message, (POP3Folder) ifolder, (POP3Store) istore, state); onDelete(context, jargs, account, folder, messages, (POP3Folder) ifolder, (POP3Store) istore, state);
break; break;
case EntityOperation.RAW: case EntityOperation.RAW:
@ -412,7 +434,7 @@ class Core {
default: default:
Log.w(folder.name + " ignored=" + op.name); Log.w(folder.name + " ignored=" + op.name);
} }
else { } else {
List<EntityMessage> messages = new ArrayList<>(); List<EntityMessage> messages = new ArrayList<>();
messages.add(message); messages.add(message);
if (similar.size() == 0) if (similar.size() == 0)
@ -852,13 +874,11 @@ class Core {
return ifolder.search(new MessageIDTerm(msgid)); return ifolder.search(new MessageIDTerm(msgid));
} }
private static Message findMessage(Context context, EntityFolder folder, EntityMessage message, POP3Store istore, POP3Folder ifolder) throws MessagingException, IOException { private static Map<EntityMessage, Message> findMessages(Context context, EntityFolder folder, List<EntityMessage> messages, POP3Store istore, POP3Folder ifolder) throws MessagingException, IOException {
Map<String, String> caps = istore.capabilities(); Map<String, String> caps = istore.capabilities();
boolean hasUidl = caps.containsKey("UIDL"); boolean hasUidl = caps.containsKey("UIDL");
Message[] imessages = ifolder.getMessages(); Message[] imessages = ifolder.getMessages();
Log.i(folder.name + " POP searching for=" + message.uidl + "/" + message.msgid +
" messages=" + imessages.length + " uidl=" + hasUidl);
if (hasUidl) { if (hasUidl) {
FetchProfile ifetch = new FetchProfile(); FetchProfile ifetch = new FetchProfile();
@ -866,21 +886,28 @@ class Core {
ifolder.fetch(imessages, ifetch); ifolder.fetch(imessages, ifetch);
} }
Map<EntityMessage, Message> result = new HashMap<>();
for (EntityMessage message : messages) {
result.put(message, null);
Log.i(folder.name + " POP searching for=" + message.uidl + "/" + message.msgid +
" messages=" + imessages.length + " uidl=" + hasUidl);
for (Message imessage : imessages) { for (Message imessage : imessages) {
MessageHelper helper = new MessageHelper((MimeMessage) imessage, context); MessageHelper helper = new MessageHelper((MimeMessage) imessage, context);
String uidl = (hasUidl ? ifolder.getUID(imessage) : null); String uidl = (hasUidl ? ifolder.getUID(imessage) : null);
String msgid = helper.getMessageID(); String msgid = (TextUtils.isEmpty(uidl) ? helper.getMessageID() : null);
if ((uidl != null && uidl.equals(message.uidl)) || if ((uidl != null && uidl.equals(message.uidl)) ||
(msgid != null && msgid.equals(message.msgid))) { (msgid != null && msgid.equals(message.msgid))) {
Log.i(folder.name + " POP found=" + uidl + "/" + msgid); Log.i(folder.name + " POP found=" + uidl + "/" + msgid);
return imessage; result.put(message, imessage);
}
} }
} }
Log.i(folder.name + " POP not found=" + message.uidl + "/" + message.msgid); return result;
return null;
} }
private static void onSetFlag(Context context, JSONArray jargs, EntityFolder folder, List<EntityMessage> messages, IMAPFolder ifolder, Flags.Flag flag) throws MessagingException, JSONException { private static void onSetFlag(Context context, JSONArray jargs, EntityFolder folder, List<EntityMessage> messages, IMAPFolder ifolder, Flags.Flag flag) throws MessagingException, JSONException {
@ -1615,7 +1642,7 @@ class Core {
} }
} }
private static void onMove(Context context, JSONArray jargs, EntityAccount account, EntityFolder folder, EntityMessage message, POP3Folder ifolder, POP3Store istore, State state) throws JSONException, FolderNotFoundException, IOException, MessagingException { private static void onMove(Context context, JSONArray jargs, EntityAccount account, EntityFolder folder, List<EntityMessage> messages, POP3Folder ifolder, POP3Store istore, State state) throws JSONException, FolderNotFoundException, IOException, MessagingException {
// Move message // Move message
DB db = DB.getInstance(context); DB db = DB.getInstance(context);
@ -1634,7 +1661,7 @@ class Core {
if (Boolean.TRUE.equals(account.leave_deleted) && if (Boolean.TRUE.equals(account.leave_deleted) &&
EntityFolder.INBOX.equals(folder.type) && EntityFolder.INBOX.equals(folder.type) &&
EntityFolder.TRASH.equals(target.type)) { EntityFolder.TRASH.equals(target.type)) {
onDelete(context, jargs, account, folder, message, ifolder, istore, state); onDelete(context, jargs, account, folder, messages, ifolder, istore, state);
return; return;
} }
@ -1646,6 +1673,7 @@ class Core {
" source=" + folder.type + " target=" + target.type + " source=" + folder.type + " target=" + target.type +
" leave deleted=" + account.leave_deleted); " leave deleted=" + account.leave_deleted);
for (EntityMessage message : messages) {
message.folder = target.id; message.folder = target.id;
if (seen) if (seen)
message.ui_seen = seen; message.ui_seen = seen;
@ -1655,6 +1683,7 @@ class Core {
db.message().updateMessage(message); db.message().updateMessage(message);
} }
}
private static void onFetch(Context context, JSONArray jargs, EntityFolder folder, IMAPStore istore, IMAPFolder ifolder, State state) throws JSONException, MessagingException, IOException { private static void onFetch(Context context, JSONArray jargs, EntityFolder folder, IMAPStore istore, IMAPFolder ifolder, State state) throws JSONException, MessagingException, IOException {
long uid = jargs.getLong(0); long uid = jargs.getLong(0);
@ -1847,17 +1876,22 @@ class Core {
} }
} }
private static void onDelete(Context context, JSONArray jargs, EntityAccount account, EntityFolder folder, EntityMessage message, POP3Folder ifolder, POP3Store istore, State state) throws MessagingException, IOException { private static void onDelete(Context context, JSONArray jargs, EntityAccount account, EntityFolder folder, List<EntityMessage> messages, POP3Folder ifolder, POP3Store istore, State state) throws MessagingException, IOException {
// Delete message // Delete message
DB db = DB.getInstance(context); DB db = DB.getInstance(context);
// Delete from server // Delete from server
if (EntityFolder.INBOX.equals(folder.type) && !account.leave_deleted) { if (EntityFolder.INBOX.equals(folder.type) && !account.leave_deleted) {
Message imessage = findMessage(context, folder, message, istore, ifolder); Map<EntityMessage, Message> map = findMessages(context, folder, messages, istore, ifolder);
for (EntityMessage message : messages) {
Message imessage = map.get(message);
if (imessage != null) { if (imessage != null) {
Log.i(folder.name + " POP delete=" + message.uidl + "/" + message.msgid); Log.i(folder.name + " POP delete=" + message.uidl + "/" + message.msgid);
imessage.setFlag(Flags.Flag.DELETED, true); imessage.setFlag(Flags.Flag.DELETED, true);
}
}
if (map.size() > 0)
try { try {
Log.i(folder.name + " POP expunge"); Log.i(folder.name + " POP expunge");
ifolder.close(true); ifolder.close(true);
@ -1867,8 +1901,8 @@ class Core {
state.error(new FolderClosedException(ifolder, "POP", new Exception(ex))); state.error(new FolderClosedException(ifolder, "POP", new Exception(ex)));
} }
} }
}
for (EntityMessage message : messages) {
// Move to trash folder // Move to trash folder
if (!EntityFolder.DRAFTS.equals(folder.type) && if (!EntityFolder.DRAFTS.equals(folder.type) &&
!EntityFolder.TRASH.equals(folder.type)) { !EntityFolder.TRASH.equals(folder.type)) {
@ -1922,6 +1956,7 @@ class Core {
} else } else
db.message().deleteMessage(message.id); db.message().deleteMessage(message.id);
} }
}
private static void onHeaders(Context context, JSONArray jargs, EntityFolder folder, EntityMessage message, IMAPFolder ifolder) throws MessagingException, IOException { private static void onHeaders(Context context, JSONArray jargs, EntityFolder folder, EntityMessage message, IMAPFolder ifolder) throws MessagingException, IOException {
// Download headers // Download headers
@ -1981,13 +2016,13 @@ class Core {
throw new IllegalArgumentException("Unexpected folder=" + folder.type); throw new IllegalArgumentException("Unexpected folder=" + folder.type);
if (message.raw == null || !message.raw) { if (message.raw == null || !message.raw) {
Message imessage = findMessage(context, folder, message, istore, ifolder); Map<EntityMessage, Message> map = findMessages(context, folder, Arrays.asList(message), istore, ifolder);
if (imessage == null) if (map.get(message) == null)
throw new IllegalArgumentException("Message not found msgid=" + message.msgid); throw new IllegalArgumentException("Message not found msgid=" + message.msgid);
File file = message.getRawFile(context); File file = message.getRawFile(context);
try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) { try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) {
imessage.writeTo(os); map.get(message).writeTo(os);
} }
DB db = DB.getInstance(context); DB db = DB.getInstance(context);

Loading…
Cancel
Save