diff --git a/Syncer.js b/Syncer.js
index 19f6d6b..3437aa2 100644
--- a/Syncer.js
+++ b/Syncer.js
@@ -2,6 +2,7 @@ const gen = require('gen-thread');
const Imap = require('imap');
const ImapManager = require('./ImapManager.js');
const EventEmitter = require('events').EventEmitter;
+const MailParser = require('mailparser').MailParser;
module.exports = Syncer;
@@ -196,8 +197,6 @@ Syncer.prototype.syncBox = function*(srv, accountId, boxName, boxKind, doFull)
account_id: accountId,
highestmodseq: 0,
kind: boxKind||''
- //unread_count: boxStatus.messages.new,
- //total_count: boxStatus.messages.total,
}).returning('id').row(gen.ef());
}
@@ -205,7 +204,7 @@ Syncer.prototype.syncBox = function*(srv, accountId, boxName, boxKind, doFull)
var missing = [];
var [ maxUid ] = yield this.pg.select('MAX(uid)').from('messages')
.where({ folder_id: boxRow.id }).val(gen.ef());
- if (boxStatus.highestmodseq)
+ if (boxRow.highestmodseq)
{
this.events.emit('sync', { state: 'start', quick: true, email: this.accounts[accountId].email, folder: boxRow.name });
process.stderr.write(this.accounts[accountId].email+'/'+boxRow.name+': quick resync\n');
@@ -227,8 +226,8 @@ Syncer.prototype.syncBox = function*(srv, accountId, boxName, boxKind, doFull)
}, (messages, state) => this.saveMessages(messages, boxRow.id, state));
yield this.pg.update('folders', {
- uidvalidity: boxRow.uidvalidity,
- highestmodseq: boxRow.highestmodseq||0
+ uidvalidity: boxStatus.uidvalidity,
+ highestmodseq: boxStatus.highestmodseq||0
}).where({ id: boxRow.id }).run(gen.ef());
}
@@ -375,6 +374,15 @@ Syncer.prototype.saveMessages = function*(messages, boxId)
yield* this.addMessage(boxId, messages[i][0], messages[i][1]);
}
+Syncer.prototype.parseMsg = function*(msg)
+{
+ var parser = new MailParser({ streamAttachments: false, defaultCharset: 'utf-8' });
+ parser.once('end', gen.cb());
+ parser.write(msg);
+ var [ obj ] = yield parser.end();
+ return obj;
+}
+
Syncer.prototype.addMessage = function*(boxId, msgrow, attrs)
{
var self = this;
@@ -383,49 +391,42 @@ Syncer.prototype.addMessage = function*(boxId, msgrow, attrs)
{
[ pgtx, end_transaction ] = yield this.pg.transaction(gen.cb(), function(e) { if (e) throw e; });
- var header = Imap.parseHeader(msgrow.headers);
- for (var i in header)
- for (var k = 0; k < header[i].length; k++)
- header[i][k] = header[i][k].replace(/\x00/g, '');
- header.from = header.from && splitEmails(header.from[0])[0];
- header.replyto = header['reply-to'] && splitEmails(header['reply-to'][0])[0];
- var re = /(<[^>]*>)/;
- header.references = (header.references && header.references[0] || '').split(re).filter(a => a.match(re));
+ let header = yield* this.parseMsg(msgrow.headers);
+ header.references = header.references || [];
if (header.references.length)
{
- if (header.references.length > 10)
- header.references = [ header.references[0] ].concat(header.references.slice(header.references.length-9));
- if (!header['in-reply-to'] || !header['in-reply-to'][0])
- header['in-reply-to'] = [ header.references[header.references.length-1] ];
- else if (header.references[header.references.length-1] != header['in-reply-to'][0])
- header.references.push(header['in-reply-to'][0]);
- }
- if (header.date)
- {
- var t = Date.parse(header.date[0]);
- if (!isNaN(t))
- header.date = new Date(t);
- else
- header.date = null;
+ if (!header.inReplyTo || !header.inReplyTo[0])
+ header.inReplyTo = [ header.references[header.references.length-1] ];
+ else if (header.references[header.references.length-1] != header.inReplyTo[0])
+ header.references.push(header.inReplyTo[0]);
}
if (!header.date)
header.date = new Date(attrs.date);
+ if (!header.from)
+ {
+ console.log(msgrow.headers);
+ console.log(header);
+ }
+ delete msgrow.headers;
msgrow.folder_id = boxId;
- msgrow.from_email = header.from && header.from.email || '';
- msgrow.from_name = header.from && header.from.name || '';
- msgrow.replyto_email = header.replyto && header.replyto.email || '';
- msgrow.replyto_name = header.replyto && header.replyto.name || '';
- msgrow.to_list = header.to && header.to[0] || '';
- msgrow.cc_list = header.cc && header.cc[0] || '';
- msgrow.bcc_list = header.bcc && header.bcc[0] || '';
- msgrow.subject = header.subject && header.subject[0] || '';
- msgrow.messageid = header['message-id'] && header['message-id'][0] || '';
- msgrow.inreplyto = header['in-reply-to'] && header['in-reply-to'][0] || '';
- msgrow.inreplyto = msgrow.inreplyto.replace(/^[\s\S]*(<[^>]*>)[\s\S]*$/, '$1');
+ msgrow.subject = header.subject || '';
+ msgrow.props = JSON.stringify({
+ from: ((header.from||[]).map((a) => [ a.name, a.address ]))[0],
+ to: (header.to||[]).map((a) => [ a.name, a.address ]),
+ cc: (header.cc||[]).map((a) => [ a.name, a.address ]),
+ bcc: (header.bcc||[]).map((a) => [ a.name, a.address ]),
+ replyto: (header.replyTo||[]).map((a) => [ a.name, a.address ]),
+ });
+ msgrow.messageid = header.messageId || '';
+ msgrow.inreplyto = header.inReplyTo && header.inReplyTo[0] || '';
msgrow.time = header.date;
+ msgrow.size = attrs.size;
msgrow.flags = toPgArray(msgrow.flags);
msgrow.refs = toPgArray(header.references);
+ for (let i in msgrow)
+ if (typeof msgrow[i] == 'string')
+ msgrow[i] = msgrow[i].replace(/\x00/g, '');
var thisIsFirst = false;
if (header.references.length)
@@ -441,7 +442,7 @@ Syncer.prototype.addMessage = function*(boxId, msgrow, attrs)
}
msgrow.thread_id = threadId;
}
- console.log(msgrow.time+' '+msgrow.from_email+' '+msgrow.subject);
+ console.log(msgrow.time+' '+(header.from && header.from[0] && header.from[0].address || '?')+' '+msgrow.subject);
[ msgrow.id ] = yield pgtx.insert('messages', msgrow).returning('id').val(gen.ef());
if (!msgrow.thread_id)
{
@@ -469,18 +470,6 @@ Syncer.prototype.addMessage = function*(boxId, msgrow, attrs)
}
}
-function splitEmails(s)
-{
- var re = /^[\s,]*(?:(?:["'](.*?)["']|([^<]+))\s*<([^>]+)>|([^<>]+)>?)/; // '
- var m, r = [];
- while (m = re.exec(s))
- {
- s = s.substr(m[0].length);
- r.push({ name: (m[1]||m[2]||'').trim(), email: (m[3]||m[4]||'').trim() });
- }
- return r;
-}
-
function toPgArray(a)
{
a = JSON.stringify(a);
diff --git a/SyncerWeb.js b/SyncerWeb.js
index 6c261f8..84483ed 100644
--- a/SyncerWeb.js
+++ b/SyncerWeb.js
@@ -175,6 +175,31 @@ function rewriteCss(ast)
}
}
+function sanitizeHtml(html)
+{
+ let styles = '';
+ html = (html||'').replace(/\n'+html;
+ styles = '';
+ }
+ html = htmlawed.sanitize(html||'', { safe: 1, elements: '* +style', keep_bad: 0, comment: 1 });
+ html = html.replace(/';
+ });
+ return html;
+}
+
function* getBody(pg, messages, boxId)
{
var p = new MailParser({ streamAttachments: false, defaultCharset: 'windows-1251' });
@@ -184,26 +209,7 @@ function* getBody(pg, messages, boxId)
p.on('end', gen.cb());
p.write(msg[0].headers);
let [ obj ] = yield p.end();
- let styles = '';
- obj.html = (obj.html||'').replace(/\n'+obj.html;
- styles = '';
- }
- obj.html = htmlawed.sanitize(obj.html||'', { safe: 1, elements: '* +style', keep_bad: 0, comment: 1 });
- obj.html = obj.html.replace(/';
- });
+ obj.html = sanitizeHtml(obj.html);
let upd = { body_text: obj.text||'', body_html: obj.html };
upd.body_html_text = obj.html.replace(/