diff --git a/Syncer.js b/Syncer.js index c764e39..5bbb514 100644 --- a/Syncer.js +++ b/Syncer.js @@ -48,7 +48,8 @@ Syncer.prototype.addAccount = function*(account) name: account.name, email: account.email, settings: { - imap: account.imap + imap: account.imap, + folders: account.folders } }).returning('*').row(gen.ef()); } @@ -447,7 +448,9 @@ Syncer.prototype.addMessage = function*(boxId, msgrow, attrs) msgrow.time = header.date; msgrow.size = attrs.size; if (!header.headers.received || !header.headers.received.length) - msgrow.flags.push('sent'); + msgrow.flags.push('out'); + else + msgrow.flags.push('in'); msgrow.flags = toPgArray(msgrow.flags); msgrow.refs = toPgArray(header.references); for (let i in msgrow) diff --git a/SyncerWeb.js b/SyncerWeb.js index 51fab36..c7793f3 100644 --- a/SyncerWeb.js +++ b/SyncerWeb.js @@ -109,13 +109,26 @@ SyncerWeb.prototype.msgSearchCond = function(query) else if (query.folderType == 'pinned') p = this.pg.sql('(flags @> array[\'flagged\']::varchar(255)[])'); else if (query.folderType == 'inbox') - p = this.pg.sql('not (flags @> array[\'sent\']::varchar(255)[])'); - else if (query.folderType == 'sent') - p = this.pg.sql('(flags @> array[\'sent\']::varchar(255)[])'); + p = this.pg.sql('(flags @> array[\'in\']::varchar(255)[])'); + else if (query.folderType == 'out') + p = this.pg.sql('(flags @> array[\'out\']::varchar(255)[])'); else if (query.folderType == 'outbox') + { + // TODO это какая-то хитрая метапапка, которая не живёт на IMAP'е? p = null; + } else if (query.folderType == 'drafts' || query.folderType == 'spam' || query.folderType == 'trash') - p = null; + { + var folders = []; + var n; + for (var id in this.syncer.accounts) + { + n = this.syncer.accounts[id].settings.folders[query.folderType]; + if (n) + folders.push(this.pg.sql.and({ 'f.name': n, 'f.account_id': id })); + } + p = this.pg.sql.or.apply(this.pg.sql.or, folders); + } if (p && query.accountId) p = this.pg.sql.and(p, this.pg.sql.eq('f.account_id', query.accountId)); return p; @@ -161,12 +174,12 @@ SyncerWeb.prototype.get_groups = function*(req, res) .where(cond) .groupBy('1, 2') .union( - this.pg.select('date_part(\'year\', m.time)::text as name, date_part(\'year\', m.time)::text||\'-01-01\' date, count(*) count') - .from('messages m') - .innerJoin('folders f', this.pg.sql('f.id=m.folder_id')) - .where(cond) - .where(this.pg.sql.lt('m.time', intervals[0].date)) - .groupBy('1, 2') + this.pg.select('y::text as name, y||\'-01-01\' date, ('+ + this.pg.select('count(*)').from('messages m') + .innerJoin('folders f', this.pg.sql('f.id=m.folder_id')) + .where(cond).where(this.pg.sql('m.time >= (t.y||\'-01-01\')::date and m.time <= (t.y||\'-12-31\')::date')) + +') count') + .from('generate_series(1970, '+(today.getFullYear()-1)+') as t (y)') ) .orderBy('date desc').rows(gen.ef()); return res.send({ groups: groups }); @@ -199,13 +212,13 @@ SyncerWeb.prototype.get_message = function*(req, res) if (this.cfg.login && (!req.session || !req.session.auth)) return res.sendStatus(401); var msgId = req.query.msgId; + console.log('fetch message '+msgId); var [ msg ] = yield this.pg.select('m.*, f.name folder_name, f.account_id') .from('messages m').join('folders f', this.pg.sql('f.id=m.folder_id')) .where({ 'm.id': msgId }).rows(gen.ef()); if (!msg.length) return res.send({ error: 'not-found' }); msg = msg[0]; - delete msg.text_index; if (!msg.body_html && !msg.body_text) { var srv = yield* this.syncer.imap.getConnection(msg.account_id, msg.folder_name); diff --git a/db.sql b/db.sql index 3e57fcc..447c174 100644 --- a/db.sql +++ b/db.sql @@ -5,11 +5,7 @@ create table accounts ( name varchar(255) not null, email varchar(255) not null, settings jsonb not null --- настройки: replyto, cc, bcc, in_server, in_port, out_server, out_port, login, password --- sent_folder, trash_folder, spam_folder, drafts_folder --- in_server varchar(255) not null, --- out_server varchar(255) not null, --- reply_to + -- настройки: replyto, cc, bcc, imap, smtp, folders ); create unique index accounts_email on accounts (email); @@ -46,7 +42,15 @@ create unique index messages_unique on messages (folder_id, uid); create index messages_flags on messages using gin (folder_id, flags); create index messages_messageid on messages (messageid); create index messages_refs on messages using gin (refs); -create index messages_time on messages (folder_id, time); +create index messages_folder_id_time on messages (folder_id, time); +create index messages_time on messages (time); +-- create or replace function immutable_year(d timestamptz) returns text +-- language plpgsql immutable as $$ +-- begin +-- return date_part('year', d); +-- end +-- $$; +-- create index messages_year on messages (immutable_year(time)); create or replace function messages_fulltext(msg messages) returns tsvector language plpgsql immutable as $$ begin