improve syncing and storing

This commit is contained in:
grimhilt
2023-03-29 16:23:24 +02:00
parent 94c7a7176b
commit e0482eb511
15 changed files with 245 additions and 347 deletions

View File

@@ -4,10 +4,10 @@ const { registerMessageInApp } = require("../saveMessage");
const { saveMessage } = require("../storeMessage");
class Box {
constructor(_imap, boxId, _boxName) {
constructor(_imap, _boxId, _boxName) {
this.imap = _imap;
this.boxName = _boxName;
this.id = boxId;
this.id = _boxId;
this.box;
this.init();
}
@@ -25,6 +25,7 @@ class Box {
sync(savedUid, currentUid) {
const promises = [];
const mails = [];
logger.log(`Syncing from ${savedUid} to ${currentUid} uid`);
const f = this.imap.seq.fetch(`${savedUid}:${currentUid}`, {
size: true,
envelope: true,
@@ -42,12 +43,29 @@ class Box {
});
f.once("end", async () => {
await Promise.all(promises).then(async (res) => {
for (let i = 0; i < mails.length; i++) {
console.log(i, mails[i].uid)
await registerMessageInApp(res[i], mails[i]);
let step = 20;
for (let i = 0; i < promises.length; i += step) {
for (let j = i; j < (i + step && promises.length); j++) {
console.log(j, promises.length, promises[j])
await new Promise((resolve, reject) => {
promises[j]
.then(async (res) => {
await registerMessageInApp(res, mails[j], this.id);
resolve();
})
.catch((err) => {
reject(err);
});
});
}
});
logger.log(`Saved messages ${i + step > promises.length ? promises.length : i + step}/${mails.length}`);
updateMailbox(this.id, mails[i].uid);
}
// await Promise.all(promises).then(async (res) => {
// for (let i = 0; i < mails.length; i++) {
// logger.log(`Saved message ${i}/${mails.length}`);
// }
// });
updateMailbox(this.id, currentUid);
});
}

View File

@@ -13,7 +13,6 @@ class ImapInstance {
port: account.port,
tls: account.tls,
});
this.account = account;
this.boxes = [];
@@ -25,11 +24,11 @@ class ImapInstance {
this.imapReady();
});
this.imap.once("error", function (err) {
this.imap.once("error", (err) => {
logger.error("Imap error for " + this.account.user + ": " + err);
});
this.imap.once("end", function () {
this.imap.once("end", () => {
logger.log("Connection ended for " + this.account.user);
});
@@ -54,10 +53,11 @@ class ImapInstance {
getAllBox(boxes) {
// ideally we should get the all box to get all messages
let allBox;
let allBox = '';
Object.keys(boxes).forEach((key) => {
if (key === "INBOX") return;
if (allBox.includes("/")) return;
if (allBox.includes("/")) return; // already found
if (!boxes[key].children) return; // no children
allBox = key;
Object.keys(boxes[key].children).forEach((childBoxes) => {
if (boxes[key].children[childBoxes].attribs.includes("\\All")) {

View File

@@ -8,8 +8,8 @@ const {
hasSameMembersAsParent,
} = require("../db/saveMessageApp");
const { findRoomByOwner, getAddresseId } = require("../db/mail");
const { isDmOnEnvelope } = require("./utils/statusUtils");
const { findRoomByOwner, getAddresseId, getUserIdOfMailbox } = require("../db/mail");
const { isDmOnEnvelope, nbMembers } = require("./utils/statusUtils");
/**
* take object address and join mailbox and host to return mailbox@host
@@ -18,25 +18,52 @@ function createAddress(elt) {
return `${elt.mailbox}@${elt.host}`;
}
async function registerMessageInApp(messageId, attrs) {
const isSeen = attrs.flags.includes("Seen") ? 1 : 0; // todo verify
async function registerMessageInApp(messageId, attrs, boxId) {
const isSeen = attrs.flags.includes("\\Seen") ? 1 : 0; // todo verify
const envelope = attrs.envelope;
await getAddresseId(createAddress(envelope.sender[0])).then(async (ownerId) => {
if (envelope.inReplyTo) {
await registerReplyMessage(envelope, messageId, isSeen, ownerId);
} else {
await findRoomByOwner(ownerId).then(async (res) => {
if (res.length == 0) {
// first message of this sender
const userId = (await getUserIdOfMailbox(boxId))[0]?.user_id;
if (ownerId == userId) {
// send by the user
if (nbMembers(envelope) == 2) {
// this is a dm
console.log(envelope)
const userTo = (await getAddresseId(createAddress(envelope.to[0])));
await findRoomByOwner(userTo).then(async (res) => {
if (res.length == 0) {
// first message of this conv with this sender
await createRoom(envelope.subject, userTo, messageId).then(async (roomId) => {
await registerMessageInRoom(messageId, roomId, isSeen, envelope.date);
});
} else {
// not a reply, add to the list of message if this sender
await registerMessageInRoom(messageId, res[0].room_id, isSeen, envelope.date);
}
});
} else {
// message coming from user with multiple member is a group
await createRoom(envelope.subject, ownerId, messageId).then(async (roomId) => {
await registerMessageInRoom(messageId, roomId, isSeen, envelope.date);
});
} else {
// not a reply, add to the list of message if this sender
await registerMessageInRoom(messageId, res[0].room_id, isSeen, envelope.date);
}
});
} else {
await findRoomByOwner(ownerId).then(async (res) => {
if (res.length == 0) {
// first message of this sender
if (!envelope.subject) console.error(envelope)
await createRoom(envelope.subject, ownerId, messageId).then(async (roomId) => {
await registerMessageInRoom(messageId, roomId, isSeen, envelope.date);
});
} else {
// not a reply, add to the list of message if this sender
await registerMessageInRoom(messageId, res[0].room_id, isSeen, envelope.date);
}
});
}
}
});
}

View File

@@ -23,8 +23,8 @@ function saveMessage(attrs, mailboxId, imap) {
return new Promise((resolve, reject) => {
registerMessage(ts, rfc822size, messageID)
.then((messageId) => {
const isSeen = attrs.flags.includes("Seen") ? 1 : 0; // todo verify
const deleted = attrs.flags.includes("Deleted") ? 1 : 0; // todo verify
const isSeen = attrs.flags.includes("\\Seen") ? 1 : 0; // todo verify
const deleted = attrs.flags.includes("\\Deleted") ? 1 : 0; // todo verify
registerMailbox_message(mailboxId, attrs.uid, messageId, attrs.modseq, isSeen, deleted);
const f = imap.fetch(attrs.uid, { bodies: "" });
@@ -57,7 +57,7 @@ function saveMessage(attrs, mailboxId, imap) {
logger.warn("Fetch error: " + err);
});
f.once("end", function () {
logger.log("Done fetching data of " + messageID);
// logger.log("Done fetching data of " + messageID); // todo
});
})
.catch((err) => {
@@ -81,8 +81,9 @@ async function saveFromParsedData(parsed, messageId) {
});
}),
);
} else if (["subject", "inReplyTo"].includes(key)) {
} else if (["subject", "inReplyTo", "references"].includes(key)) {
// todo : "references" (array)
if (key == "references") return;
promises.push(
getFieldId(key).then(async (fieldId) => {
await saveHeader_fields(messageId, fieldId, undefined, undefined, parsed[key]);
@@ -93,13 +94,7 @@ async function saveFromParsedData(parsed, messageId) {
const size = "0";
saveBodypart(size, hash, parsed[key], "").then((bodypartId) => {
getFieldId(key).then((fieldId) => {
saveHeader_fields(
messageId,
fieldId,
bodypartId,
undefined, // todo ?
undefined,
);
saveHeader_fields(messageId, fieldId, bodypartId, undefined, undefined);
});
});
} else if (key == "attachments") {

View File

@@ -1,13 +1,23 @@
function isDmOnEnvelope(envelope) {
const members =
envelope.bcc?.length +
envelope.cc?.length +
envelope.to?.length +
envelope.sender?.length +
envelope.from?.length;
return members === 2;
return nbMembers(envelope) === 2;
}
function nbMembers(envelope) {
let nbMembers =
(envelope.bcc?.length ?? 0) +
(envelope.cc?.length ?? 0) +
(envelope.to?.length ?? 0) +
(envelope.from?.length ?? 0);
if (
envelope.sender?.length > 0 &&
!(envelope.sender[0].mailbox == envelope.from[0].mailbox && envelope.sender[0].host == envelope.from[0].host)
) {
nbMembers += envelope.sender?.length ?? 0;
}
return nbMembers;
}
module.exports = {
isDmOnEnvelope,
nbMembers,
};