summaryrefslogtreecommitdiff
path: root/app/imap.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/imap.js')
-rw-r--r--app/imap.js66
1 files changed, 59 insertions, 7 deletions
diff --git a/app/imap.js b/app/imap.js
index 181d9cf..4041089 100644
--- a/app/imap.js
+++ b/app/imap.js
@@ -5,6 +5,13 @@ ipcMain.on('imap:listTree:from', listTreeFrom);
ipcMain.on('imap:listTree:to', listTreeTo);
ipcMain.on('imap:migrate', migrate);
+/**
+ * Connect to server
+ *
+ * @param {object} options
+ *
+ * @returns {Promise<ImapFlow>}
+ */
async function connect (options) {
const client = new ImapFlow({
host: options.server,
@@ -13,6 +20,7 @@ async function connect (options) {
user: options.username,
pass: options.password,
},
+ tls: options.tls,
});
await client.connect();
@@ -20,6 +28,15 @@ async function connect (options) {
return client;
}
+/**
+ * Turn fetch response into array
+ *
+ * @param {string} range
+ * @param {object} query
+ * @param {object} options
+ *
+ * @returns {Promise<*[]>}
+ */
ImapFlow.prototype.fetchArray = async function (range, query, options = {}) {
const msgsGenerator = await this.fetch(range, query, options);
const msgs = [];
@@ -30,45 +47,80 @@ ImapFlow.prototype.fetchArray = async function (range, query, options = {}) {
return msgs;
};
+/**
+ * @param {IpcMainEvent} event
+ * @param {object} options
+ */
async function listTreeFrom (event, options) {
- const client = await connect(options);
+ try {
+ const client = await connect(options);
- event.reply('imap:listTree:from:reply', await client.listTree());
- await client.logout();
+ event.reply('imap:listTree:from:reply', await client.listTree());
+ await client.logout();
+ } catch (e) {
+ event.reply('imap:from:error', e);
+ }
}
+/**
+ * @param {IpcMainEvent} event
+ * @param {object} options
+ */
async function listTreeTo (event, options) {
- const client = await connect(options);
+ try {
+ const client = await connect(options);
- event.reply('imap:listTree:to:reply', await client.listTree());
- await client.logout();
+ event.reply('imap:listTree:to:reply', await client.listTree());
+ await client.logout();
+ } catch (e) {
+ event.reply('imap:to:error', e);
+ }
}
+/**
+ * @param {IpcMainEvent} event
+ * @param {object} from
+ * @param {object} to
+ */
async function migrate (event, { from, to }) {
const fromClient = await connect(from);
const toClient = await connect(to);
+ event.reply('imap:migrate:progress', 'Getting folders');
const fromFolders = (await fromClient.list()).filter((folder) => folder.subscribed);
for (const fromFolder of fromFolders) {
+ event.reply('imap:migrate:progress', `Working on folder "${fromFolder.path}"`);
+
try {
await toClient.mailboxCreate(fromFolder.path);
} catch (e) {}
+ const appendCommands = [];
const fromMailbox = await fromClient.getMailboxLock(fromFolder.path);
const toMailbox = await toClient.getMailboxLock(fromFolder.path);
try {
+ event.reply('imap:migrate:progress', '- Collecting messages from target for comparison');
const toMsgs = await toClient.fetchArray('1:*', { flags: true, envelope: true, source: true });
+
+ event.reply('imap:migrate:progress', '- Collecting messages from source');
const fromMsgs = await fromClient.fetchArray('1:*', { flags: true, envelope: true, source: true });
+ event.reply('imap:migrate:progress', '- Comparing messages');
const msgs = fromMsgs.filter((fromMsg) => !toMsgs.some((toMsg) => Buffer.compare(toMsg.source, fromMsg.source) === 0));
+ event.reply('imap:migrate:progress', `- Message status: Found ${fromMsgs.length} messages total and ${msgs.length} new messages to migrate`);
+
await toClient.noop();
for (const msg of msgs) {
- toClient.append(fromFolder.path, msg.source, Array.from(msg.flags), msg.envelope.date);
+ appendCommands.push(toClient.append(fromFolder.path, msg.source, Array.from(msg.flags), msg.envelope.date));
}
} finally {
+ await Promise.all(appendCommands);
+ event.reply('imap:migrate:progress', '- Done');
fromMailbox.release();
toMailbox.release();
}
}
+
+ event.reply('imap:migrate:progress', 'Done');
}