mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-12-29 20:04:59 +08:00
Fix associations
This commit is contained in:
parent
e64c2ae4c0
commit
cb95574378
2 changed files with 117 additions and 18 deletions
|
@ -28,8 +28,9 @@ module.exports = (sequelize, Sequelize) => {
|
|||
},
|
||||
],
|
||||
classMethods: {
|
||||
associate: ({Category}) => {
|
||||
associate: ({Category, Thread}) => {
|
||||
Message.belongsTo(Category)
|
||||
Message.belongsTo(Thread)
|
||||
},
|
||||
hashForHeaders: (headers) => {
|
||||
return crypto.createHash('sha256').update(headers, 'utf8').digest('hex');
|
||||
|
|
|
@ -4,7 +4,8 @@ function processMessage({message, accountId}) {
|
|||
return DatabaseConnectionFactory.forAccount(accountId)
|
||||
.then((db) => addMessageToThread({db, accountId, message}))
|
||||
.then((thread) => {
|
||||
thread.setMessages([message])
|
||||
thread.addMessage(message)
|
||||
message.setThread(thread)
|
||||
return message
|
||||
})
|
||||
}
|
||||
|
@ -12,27 +13,19 @@ function processMessage({message, accountId}) {
|
|||
function addMessageToThread({db, accountId, message}) {
|
||||
const {Thread, Message} = db
|
||||
if (message.threadId) {
|
||||
return Thread.findOne({
|
||||
where: {
|
||||
threadId: message.threadId,
|
||||
}
|
||||
})
|
||||
return Thread.find({where: {threadId: message.threadId}})
|
||||
}
|
||||
return matchThread({db, accountId, message})
|
||||
.then((thread) => {
|
||||
if (thread) {
|
||||
return thread
|
||||
}
|
||||
return Thread.create({
|
||||
subject: message.subject,
|
||||
cleanedSubject: cleanSubject(message.subject),
|
||||
})
|
||||
})
|
||||
.then((thread) => (thread))
|
||||
}
|
||||
|
||||
function matchThread({db, accountId, message}) {
|
||||
if (message.headers.inReplyTo) {
|
||||
return getThreadFromHeader()
|
||||
const {Thread} = db
|
||||
|
||||
// TODO: Add once we have some test data with this header
|
||||
/*
|
||||
if (message.headers['in-reply-to']) {
|
||||
return getThreadFromHeader() // Doesn't exist yet
|
||||
.then((thread) => {
|
||||
if (thread) {
|
||||
return thread
|
||||
|
@ -43,12 +36,117 @@ function matchThread({db, accountId, message}) {
|
|||
})
|
||||
})
|
||||
}
|
||||
*/
|
||||
return Thread.create({
|
||||
subject: message.subject,
|
||||
cleanedSubject: cleanSubject(message.subject),
|
||||
})
|
||||
}
|
||||
|
||||
function cleanSubject(subject) {
|
||||
if (subject === null)
|
||||
return ""
|
||||
const regex = new RegExp(/^((re|fw|fwd|aw|wg|undeliverable|undelivered):\s*)+/ig)
|
||||
const cleanedSubject = subject.replace(regex, (match) => "")
|
||||
return cleanedSubject
|
||||
}
|
||||
|
||||
// TODO: Incorporate this more elaborate threading algorithm
|
||||
/*
|
||||
function fetchCorrespondingThread({db, accountId, message}) {
|
||||
const cleanedSubject = cleanSubject(message.subject)
|
||||
return getThreads({db, message, cleanedSubject})
|
||||
.then((threads) => {
|
||||
return findCorrespondingThread({message, threads})
|
||||
})
|
||||
}
|
||||
|
||||
function getThreads({db, message, cleanedSubject}) {
|
||||
const {Thread} = db
|
||||
return Thread.findAll({
|
||||
where: {
|
||||
threadId: message.headers.threadId,
|
||||
cleanedSubject: cleanedSubject,
|
||||
},
|
||||
order: [
|
||||
['id', 'DESC']
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
function findCorrespondingThread({message, threads}) {
|
||||
for (const thread of threads) {
|
||||
for (const match of thread.messages) {
|
||||
// Ignore BCC
|
||||
const {matchEmails, messageEmails} = removeBccParticipants({message, match})
|
||||
|
||||
// A thread is probably related if it has more than two common participants
|
||||
const intersectingParticipants = getIntersectingParticipants({messageEmails, matchEmails})
|
||||
if (intersectingParticipants.length >= 2) {
|
||||
if (thread.messages.length >= MAX_THREAD_LENGTH)
|
||||
break
|
||||
return match.thread
|
||||
}
|
||||
|
||||
// Handle case for self-sent emails
|
||||
if (!message.from || !message.to)
|
||||
return
|
||||
if (isSentToSelf({message, match})) {
|
||||
if (thread.messages.length >= MAX_THREAD_LENGTH)
|
||||
break
|
||||
return match.thread
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removeBccParticipants({message, match}) {
|
||||
const matchBcc = match.bcc ? match.bcc : []
|
||||
const messageBcc = message.bcc ? message.bcc : []
|
||||
let matchEmails = match.participants.filter((participant) => {
|
||||
return matchBcc.find(bcc => bcc === participant)
|
||||
})
|
||||
matchEmails.map((email) => {
|
||||
return email[1]
|
||||
})
|
||||
let messageEmails = message.participants.filter((participant) => {
|
||||
return messageBcc.find(bcc => bcc === participant)
|
||||
})
|
||||
messageEmails.map((email) => {
|
||||
return email[1]
|
||||
})
|
||||
return {messageEmails, matchEmails}
|
||||
}
|
||||
|
||||
function getIntersectingParticipants({messageEmails, matchEmails}) {
|
||||
const matchParticipants = new Set(matchEmails)
|
||||
const messageParticipants = new Set(messageEmails)
|
||||
const intersectingParticipants = new Set([...matchParticipants]
|
||||
.filter(participant => messageParticipants.has(participant)))
|
||||
return intersectingParticipants
|
||||
}
|
||||
|
||||
function isSentToSelf({message, match}) {
|
||||
const matchFrom = match.from.map((participant) => {
|
||||
return participant[1]
|
||||
})
|
||||
const matchTo = match.to.map((participant) => {
|
||||
return participant[1]
|
||||
})
|
||||
const messageFrom = message.from.map((participant) => {
|
||||
return participant[1]
|
||||
})
|
||||
const messageTo = message.to.map((participant) => {
|
||||
return participant[1]
|
||||
})
|
||||
|
||||
return (messageTo.length === 1 &&
|
||||
messageFrom === messageTo &&
|
||||
matchFrom === matchTo &&
|
||||
messageTo === matchFrom)
|
||||
}
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
order: 0,
|
||||
processMessage,
|
||||
|
|
Loading…
Reference in a new issue