diff --git a/.gitignore b/.gitignore index f356293..a57a19f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ logs results npm-debug.log +node_modules/ diff --git a/README.md b/README.md index ff315c1..5c94476 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,31 @@ -node-maildir -============ +# Maildir++ A Maildir++ library for nodejs + +## Installation + +```sh +npm install --save maildir-plus +``` + +## Usage + +```javascript + +var Maildir = require('maildir-plus'); + +/* using events */ +var maildir = new Maildir('/path/to/maildir'); +maildir.on('error', function(err) { + // do something about it... +}); +maildir.on('ready', function() { + // maildir ok +}); + +/* with a classic callback */ +var maildir = new Maildir('/path/to/maildir', function(err) { + // ... +}); + +``` diff --git a/mailbox.js b/mailbox.js new file mode 100644 index 0000000..08a7f3b --- /dev/null +++ b/mailbox.js @@ -0,0 +1,84 @@ + +var EventEmitter = require('events').EventEmitter; +var crypto = require('crypto'); +var path = require('path'); +var fs = require('fs'); + +var async = require('async'); +var mkdirp = require('mkdirp'); + +function Mailbox(dir, create, cb, _exists) { + EventEmitter.call(this); + this.dir = dir; + + this.uid_list = null; + this.uid_map = null; + this.flags_map = null; + + this.uid_validity = 0; + this.uid_next = 1; + + if(_exists) { + return this; + } + if(typeof create == 'function') { + cb = create; + create = false; + } + if(create) { + Mailbox.create(dir, this, cb); + return this; + } + + this.open(cb); +} +module.exports = Mailbox; +Mailbox.prototype = Object.create(EventEmitter.prototype); + +Mailbox.create = function(dir, open, cb) { + if(typeof open == 'function') { + cb = open; + open = false; + } + else { + // ensure not null nor undefined + open = open || false; + } + // cb is not mandatory when called from `new Maildir(dir, true)` + if(typeof cb != 'function' && (!open.constructor || open.constructor != Mailbox)) { + var e = new TypeError('A callback is required'); + Error.captureStackTrace(e, Mailbox.create); + throw e; + } + + function onError(err) { + if(typeof cb == 'function') { + cb(err); + } + else { + open.emit('error', err); + } + } + + async.series({ + _dir: mkdirp.bind(null, dir), + uid_list: fs.open.bind(fs, path.join(dir, 'uid-list'), 'w+'), + uid_map: fs.open.bind(fs, path.join(dir, 'uid-map'), 'w+'), + flags_map: fs.open.bind(fs, path.join(dir, 'flags-map'), 'w+') + }, function(err, res) { + if(err) { + return onError(err); + } + var uid_validity = crypto.randomBytes(4).readInt32BE(0) & 0x7fffffff; + }); +}; + +Mailbox.prototype.open = function() { + async.parallel({ + uid_list: fs.open.bind(fs, path.join(dir, 'uid-list'), 'r+'), + uid_map: fs.open.bind(fs, path.join(dir, 'uid-map'), 'r+'), + flags_map: fs.open.bind(fs, path.join(dir, 'flags-map'), 'r+') + }, function(err, res) { + // + }); +}; diff --git a/maildir.js b/maildir.js new file mode 100644 index 0000000..7d49581 --- /dev/null +++ b/maildir.js @@ -0,0 +1,95 @@ + +var EventEmitter = require('events').EventEmitter; +var fs = require('fs'); +var path = require('path'); + +var async = require('async'); +var mkdirp = require('mkdirp'); + +var Mailbox = require('./mailbox.js'); + +function Maildir(dir, create, cb, _exists) { + EventEmitter.call(this); + this.dir = dir; + + if(_exists) { + return this; + } + if(typeof create == 'function') { + cb = create; + create = false; + } + if(create) { + Maildir.create(dir, this, cb); + return this; + } + + + var mdir = this; + async.map([ + path.join(dir, 'new'), + path.join(dir, 'cur'), + path.join(dir, 'tmp') + ], fs.stat, function(err) { + if(typeof cb == 'function') { + return cb(err, mdir); + } + if(err) { + mdir.emit('error', err); + } + else { + mdir.emit('ready', mdir); + } + }); +} +Maildir.prototype = Object.create(EventEmitter); +module.exports = Maildir; +Maildir.Mailbox = Mailbox; + +Maildir.create = function(dir, open, cb) { + if(typeof open == 'function') { + cb = open; + open = false; + } + else { + // ensure not null nor undefined + open = open || false; + } + // cb is not mandatory when called from `new Maildir(dir, true)` + if(typeof cb != 'function' && (!open.constructor || open.constructor != Maildir)) { + var e = new TypeError('A callback is required'); + Error.captureStackTrace(e, Maildir.create); + throw e; + } + var INBOX = path.join(dir, 'cur'); + async.map([ + path.join(dir, 'new'), // recents emails + path.join(dir, 'tmp') + ], mkdirp, function(err, res) { + if(err) { + return cb(err); + } + if(!open) { + return Mailbox.create(mbox, cb); + } + Mailbox.create(INBOX, function(err) { + var mDir = open.constructor && open.constructor === Maildir && open; + if(typeof cb != 'function') { + return err && open.emit('error', err) || open.emit('ready', open); + } + cb(err || null, !err && mDir || !err && new Maildir(dir, null, null, true)); + }); + }); +}; + +Maildir.prototype.open = function(name, create, cb) { + // +}; + +Maildir.prototype.create = function(name, open, cb) { + // +}; + + + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..be42513 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "maildir-plus", + "version": "0.0.1", + "description": "A Maildir++ library for nodejs", + "main": "maildir.js", + "repository": { + "type": "git", + "url": "git://github.com/xpensia/node-maildir.git" + }, + "keywords": [ + "maildir", + "maildir++", + "email", + "mail" + ], + "author": { + "name": "Jean-Sébastien Tremblay", + "email": "jeansebtr@xpensia.com", + "url": "http://blog.jeansebtr.com/" + }, + "license": "MIT", + "readmeFilename": "README.md", + "gitHead": "d386be2042e3f9a574e6f8b1906a098584c621e8", + "dependencies": { + "async": "0.2.x", + "mkdirp": "0.3.x" + } +}