Add namespaced sequence number-based functions and remove some unnecessary try-catch blocks

fork
Brian White 13 years ago
parent 3b8695dd34
commit c77f652a28

@ -317,6 +317,8 @@ ImapConnection Functions
* **removeDeleted**(Function) - _(void)_ - Permanently removes (EXPUNGEs) all messages flagged as Deleted in the mailbox that is currently open. The Function parameter is the callback with one parameter: the error (null if none). **Note:** At least on Gmail, performing this operation with any currently open mailbox that is not the Spam or Trash mailbox will merely archive any messages marked as Deleted (by moving them to the 'All Mail' mailbox). * **removeDeleted**(Function) - _(void)_ - Permanently removes (EXPUNGEs) all messages flagged as Deleted in the mailbox that is currently open. The Function parameter is the callback with one parameter: the error (null if none). **Note:** At least on Gmail, performing this operation with any currently open mailbox that is not the Spam or Trash mailbox will merely archive any messages marked as Deleted (by moving them to the 'All Mail' mailbox).
**All functions below have sequence number-based counterparts that can be accessed by using the 'seq' namespace of the imap connection's instance (e.g. conn.seq.search() returns sequence numbers instead of unique ids, conn.seq.fetch() fetches by sequence number(s) instead of unique ids, etc):**
* **search**(Array, Function) - _(void)_ - Searches the currently open mailbox for messages using specific criterion. The Function parameter is the callback with two parameters: the error (null if none) and an Array containing the message IDs matching the search criterion. The Array parameter is a list of Arrays containing the criterion (and any required arguments) to be used. Prefix the criteria name with an "!" to negate. For example, to search for unread messages since April 20, 2010 you could use: [ 'UNSEEN', ['SINCE', 'April 20, 2010'] ]. To search for messages that are EITHER unread OR are dated April 20, 2010 or later, you could use: [ ['OR', 'UNSEEN', ['SINCE', 'April 20, 2010'] ] ]. * **search**(Array, Function) - _(void)_ - Searches the currently open mailbox for messages using specific criterion. The Function parameter is the callback with two parameters: the error (null if none) and an Array containing the message IDs matching the search criterion. The Array parameter is a list of Arrays containing the criterion (and any required arguments) to be used. Prefix the criteria name with an "!" to negate. For example, to search for unread messages since April 20, 2010 you could use: [ 'UNSEEN', ['SINCE', 'April 20, 2010'] ]. To search for messages that are EITHER unread OR are dated April 20, 2010 or later, you could use: [ ['OR', 'UNSEEN', ['SINCE', 'April 20, 2010'] ] ].
* The following message flags are valid criterion and do not require values: * The following message flags are valid criterion and do not require values:
* 'ALL' - All messages. * 'ALL' - All messages.

@ -68,6 +68,9 @@ function ImapConnection (options) {
util.inherits(ImapConnection, EventEmitter); util.inherits(ImapConnection, EventEmitter);
exports.ImapConnection = ImapConnection; exports.ImapConnection = ImapConnection;
/* Namespace for seqno-based commands */
ImapConnection.prototype.seq = {};
ImapConnection.prototype.connect = function(loginCb) { ImapConnection.prototype.connect = function(loginCb) {
var self = this, var self = this,
fnInit = function() { fnInit = function() {
@ -599,16 +602,28 @@ ImapConnection.prototype.renameBox = function(oldname, newname, cb) {
this._send('RENAME "' + escape(oldname) + '" "' + escape(newname) + '"', cb); this._send('RENAME "' + escape(oldname) + '" "' + escape(newname) + '"', cb);
}; };
ImapConnection.prototype.seq.search = function(options, cb) {
this._search('', options, cb);
};
ImapConnection.prototype.search = function(options, cb) { ImapConnection.prototype.search = function(options, cb) {
this._search('UID ', options, cb);
};
ImapConnection.prototype._search = function(which, options, cb) {
if (this._state.status !== STATES.BOXSELECTED) if (this._state.status !== STATES.BOXSELECTED)
throw new Error('No mailbox is currently selected'); throw new Error('No mailbox is currently selected');
if (!Array.isArray(options)) if (!Array.isArray(options))
throw new Error('Expected array for search options'); throw new Error('Expected array for search options');
this._send('UID SEARCH' this._send(which + 'SEARCH'
+ buildSearchQuery(options, this.capabilities), cb); + buildSearchQuery(options, this.capabilities), cb);
}; };
ImapConnection.prototype.seq.fetch = function(seqnos, options) {
return this._fetch('', seqnos, options);
};
ImapConnection.prototype.fetch = function(uids, options) { ImapConnection.prototype.fetch = function(uids, options) {
return this._fetch('UID ', uids, options);
};
ImapConnection.prototype._fetch = function(which, uids, options) {
if (this._state.status !== STATES.BOXSELECTED) if (this._state.status !== STATES.BOXSELECTED)
throw new Error('No mailbox is currently selected'); throw new Error('No mailbox is currently selected');
@ -618,11 +633,7 @@ ImapConnection.prototype.fetch = function(uids, options) {
if (!Array.isArray(uids)) if (!Array.isArray(uids))
uids = [uids]; uids = [uids];
try { validateUIDList(uids);
validateUIDList(uids);
} catch(e) {
throw e;
}
var opts = { var opts = {
markSeen: false, markSeen: false,
@ -630,7 +641,7 @@ ImapConnection.prototype.fetch = function(uids, options) {
struct: true, struct: true,
headers: true, // \_______ at most one of these can be used for any given headers: true, // \_______ at most one of these can be used for any given
// _______ fetch request // _______ fetch request
body: false // / body: false // /
} }
}, toFetch, bodyRange = '', self = this; }, toFetch, bodyRange = '', self = this;
if (typeof options !== 'object') if (typeof options !== 'object')
@ -679,7 +690,8 @@ ImapConnection.prototype.fetch = function(uids, options) {
if (this.capabilities.indexOf('X-GM-EXT-1') > -1) if (this.capabilities.indexOf('X-GM-EXT-1') > -1)
extensions = 'X-GM-THRID X-GM-MSGID X-GM-LABELS '; extensions = 'X-GM-THRID X-GM-MSGID X-GM-LABELS ';
this._send('UID FETCH ' + uids.join(',') + ' (' + extensions + 'FLAGS INTERNALDATE' this._send(which + 'FETCH ' + uids.join(',') + ' (' + extensions
+ 'FLAGS INTERNALDATE'
+ (opts.request.struct ? ' BODYSTRUCTURE' : '') + (opts.request.struct ? ' BODYSTRUCTURE' : '')
+ (typeof toFetch === 'string' ? ' BODY' + (typeof toFetch === 'string' ? ' BODY'
+ (!opts.markSeen ? '.PEEK' : '') + (!opts.markSeen ? '.PEEK' : '')
@ -698,54 +710,64 @@ ImapConnection.prototype.fetch = function(uids, options) {
return imapFetcher; return imapFetcher;
}; };
ImapConnection.prototype.seq.addFlags = function(seqnos, flags, cb) {
this._store('', seqnos, flags, true, cb);
};
ImapConnection.prototype.addFlags = function(uids, flags, cb) { ImapConnection.prototype.addFlags = function(uids, flags, cb) {
try { this._store('UID ', uids, flags, true, cb);
this._store(uids, flags, true, cb);
} catch (err) {
throw err;
}
}; };
ImapConnection.prototype.seq.delFlags = function(seqnos, flags, cb) {
this._store('', seqnos, flags, false, cb);
};
ImapConnection.prototype.delFlags = function(uids, flags, cb) { ImapConnection.prototype.delFlags = function(uids, flags, cb) {
try { this._store('UID ', uids, flags, false, cb);
this._store(uids, flags, false, cb);
} catch (err) {
throw err;
}
}; };
ImapConnection.prototype.seq.addKeywords = function(seqnos, flags, cb) {
return this._addKeywords('', seqnos, flags, cb);
};
ImapConnection.prototype.addKeywords = function(uids, flags, cb) { ImapConnection.prototype.addKeywords = function(uids, flags, cb) {
return this._addKeywords('UID ', uids, flags, cb);
};
ImapConnection.prototype._addKeywords = function(which, uids, flags, cb) {
if (!this._state.box._newKeywords) if (!this._state.box._newKeywords)
throw new Error('This mailbox does not allow new keywords to be added'); throw new Error('This mailbox does not allow new keywords to be added');
try { this._store(which, uids, flags, true, cb);
this._store(uids, flags, true, cb);
} catch (err) {
throw err;
}
}; };
ImapConnection.prototype.seq.delKeywords = function(seqnos, flags, cb) {
this._store('', seqnos, flags, false, cb);
};
ImapConnection.prototype.delKeywords = function(uids, flags, cb) { ImapConnection.prototype.delKeywords = function(uids, flags, cb) {
try { this._store('UID ', uids, flags, false, cb);
this._store(uids, flags, false, cb);
} catch (err) {
throw err;
}
}; };
ImapConnection.prototype.seq.copy = function(seqnos, boxTo, cb) {
return this._copy('', seqnos, boxTo, cb);
};
ImapConnection.prototype.copy = function(uids, boxTo, cb) { ImapConnection.prototype.copy = function(uids, boxTo, cb) {
return this._copy('UID ', uids, boxTo, cb);
};
ImapConnection.prototype._copy = function(which, uids, boxTo, cb) {
if (this._state.status !== STATES.BOXSELECTED) if (this._state.status !== STATES.BOXSELECTED)
throw new Error('No mailbox is currently selected'); throw new Error('No mailbox is currently selected');
if (!Array.isArray(uids)) if (!Array.isArray(uids))
uids = [uids]; uids = [uids];
try {
validateUIDList(uids); validateUIDList(uids);
} catch(e) {
throw e; this._send(which + 'COPY ' + uids.join(',') + ' "' + escape(boxTo) + '"', cb);
}
this._send('UID COPY ' + uids.join(',') + ' "' + escape(boxTo) + '"', cb);
}; };
ImapConnection.prototype.seq.move = function(seqnos, boxTo, cb) {
return this._move('', seqnos, boxTo, cb);
};
ImapConnection.prototype.move = function(uids, boxTo, cb) { ImapConnection.prototype.move = function(uids, boxTo, cb) {
return this._move('UID ', uids, boxTo, cb);
};
ImapConnection.prototype._move = function(which, uids, boxTo, cb) {
var self = this; var self = this;
if (this._state.status !== STATES.BOXSELECTED) if (this._state.status !== STATES.BOXSELECTED)
throw new Error('No mailbox is currently selected'); throw new Error('No mailbox is currently selected');
@ -753,7 +775,8 @@ ImapConnection.prototype.move = function(uids, boxTo, cb) {
throw new Error('Cannot move message: ' throw new Error('Cannot move message: '
+ 'server does not allow deletion of messages'); + 'server does not allow deletion of messages');
} else { } else {
self.copy(uids, boxTo, function(err, reentryCount, deletedUIDs, counter) { self._copy(which, uids, boxTo, function(err, reentryCount, deletedUIDs,
counter) {
if (err) { if (err) {
cb(err); cb(err);
return; return;
@ -806,20 +829,18 @@ ImapConnection.prototype._fnTmrConn = function(loginCb) {
this._state.conn.destroy(); this._state.conn.destroy();
} }
ImapConnection.prototype._store = function(uids, flags, isAdding, cb) { ImapConnection.prototype._store = function(which, uids, flags, isAdding, cb) {
var isKeywords = (arguments.callee.caller === this.addKeywords var isKeywords = (arguments.callee.caller === this.addKeywords
|| arguments.callee.caller === this.delKeywords); || arguments.callee.caller === this.delKeywords);
if (this._state.status !== STATES.BOXSELECTED) if (this._state.status !== STATES.BOXSELECTED)
throw new Error('No mailbox is currently selected'); throw new Error('No mailbox is currently selected');
if (typeof uids === 'undefined') if (typeof uids === 'undefined')
throw new Error('The message ID(s) must be specified'); throw new Error('The message ID(s) must be specified');
if (!Array.isArray(uids)) if (!Array.isArray(uids))
uids = [uids]; uids = [uids];
try { validateUIDList(uids);
validateUIDList(uids);
} catch(e) {
throw e;
}
if ((!Array.isArray(flags) && typeof flags !== 'string') if ((!Array.isArray(flags) && typeof flags !== 'string')
|| (Array.isArray(flags) && flags.length === 0)) || (Array.isArray(flags) && flags.length === 0))
throw new Error((isKeywords ? 'Keywords' : 'Flags') throw new Error((isKeywords ? 'Keywords' : 'Flags')
@ -846,7 +867,7 @@ ImapConnection.prototype._store = function(uids, flags, isAdding, cb) {
flags = flags.join(' '); flags = flags.join(' ');
cb = arguments[arguments.length-1]; cb = arguments[arguments.length-1];
this._send('UID STORE ' + uids.join(',') + ' ' + (isAdding ? '+' : '-') this._send(which + 'STORE ' + uids.join(',') + ' ' + (isAdding ? '+' : '-')
+ 'FLAGS.SILENT (' + flags + ')', cb); + 'FLAGS.SILENT (' + flags + ')', cb);
}; };
@ -1046,11 +1067,7 @@ function buildSearchQuery(options, extensions, isOrChild) {
if (!args) if (!args)
throw new Error('Incorrect number of arguments for search option: ' throw new Error('Incorrect number of arguments for search option: '
+ criteria); + criteria);
try { validateUIDList(args);
validateUIDList(args);
} catch(e) {
throw e;
}
searchargs += modifier + criteria + ' ' + args.join(','); searchargs += modifier + criteria + ' ' + args.join(',');
break; break;
// -- Extensions criteria -- // -- Extensions criteria --
@ -1107,7 +1124,7 @@ function validateUIDList(uids) {
} }
intval = parseInt(''+uids[i]); intval = parseInt(''+uids[i]);
if (isNaN(intval)) { if (isNaN(intval)) {
throw new Error('Message ID must be an integer, "*", or a range: ' throw new Error('Message ID/number must be an integer, "*", or a range: '
+ uids[i]); + uids[i]);
} else if (typeof uids[i] !== 'number') } else if (typeof uids[i] !== 'number')
uids[i] = intval; uids[i] = intval;

Loading…
Cancel
Save