<commit_before>/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
/*global define, appshell, $, window */

define(function (require, exports, module) {
    "use strict";

    var FileSystemError = require("filesystem/FileSystemError"),
        FileSystemStats = require("filesystem/FileSystemStats"),
        Dialogs         = require("widgets/Dialogs"),
        DefaultDialogs  = require("widgets/DefaultDialogs"),
        // TODO: we have to figure out how we're going to build/deploy makedrive.js, this is hacky.
        MakeDrive       = require("thirdparty/makedrive/client/dist/makedrive"),
        OpenDialog      = require("filesystem/impls/makedrive/open-dialog");

    var fs              = MakeDrive.fs(),
        Path            = MakeDrive.Path,
        watchers        = {};

    var _changeCallback;            // Callback to notify FileSystem of watcher changes

    // Give extensions access to MakeDrive's sync functionality. The hosting app
    // needs to call sync.connect(serverURL) when the user is logged in, for example.
    appshell.MakeDrive = MakeDrive;

    // TODO: Maybe use an XHR or something else other than this?
    $.get( "http://localhost:9090/api/sync", function( data ) {
      fs.sync.connect('ws://localhost:9090', data);
    });

    var sync = fs.sync;

    //TODO: Do we want to do anything other than console.log for all these events?
    sync.on('syncing', function() {
        console.log('sync started');
    });
    sync.on('error', function(e) {
        console.log('sync error: ', e);
    });
    sync.on('completed', function() {
        console.log('sync completed');
    });
    sync.on('updates', function() {
        console.log('server has updates');
    });

    // TODO: Figure out when is the best time to start the sync.
    var DocumentManager = brackets.getModule('document/DocumentManager');
    $(DocumentManager).on("documentSaved", function(err, e) {
        sync.request('/' + e.file._path);
    });

    function showOpenDialog(allowMultipleSelection, chooseDirectories, title, initialPath, fileTypes, callback) {
        OpenDialog.showOpenDialog.apply(null, arguments);
    }

    function showSaveDialog(title, initialPath, defaultName, callback) {
        var selectedPath;
        var saveResponse = window.prompt(title, defaultName);
        if(saveResponse){
            initialPath = initialPath || '/';
            selectedPath = initialPath + saveResponse;
            callback(null, selectedPath);
        }
        else{
            callback();
        }
    }

    /**
     * Convert Filer error codes to FileSystemError values.
     *
     * @param {?number} err A Filer error code
     * @return {?string} A FileSystemError string, or null if there was no error code.
     * @private
     **/
    function _mapError(err) {
        if (!err) {
            return null;
        }

        switch (err.code) {
        case 'EINVAL':
            return FileSystemError.INVALID_PARAMS;
        case 'ENOENT':
            return FileSystemError.NOT_FOUND;
        case 'EROFS':
            return FileSystemError.NOT_WRITABLE;
        case 'ENOSPC':
            return FileSystemError.OUT_OF_SPACE;
        case 'ENOTEMPTY':
        case 'EEXIST':
            return FileSystemError.ALREADY_EXISTS;
        case 'ENOTDIR':
            return FileSystemError.INVALID_PARAMS;
        case 'EBADF':
            return FileSystemError.NOT_READABLE;
        }

        return FileSystemError.UNKNOWN;
    }

    /**
     * Convert a callback to one that transforms its first parameter from a
     * Filer error code to a FileSystemError string.
     *
     * @param {function(?number)} cb A callback that expects an Filer error code
     * @return {function(?string)} A callback that expects a FileSystemError string
     * @private
     **/
    function _wrap(cb) {
        return function (err) {
            var args = Array.prototype.slice.call(arguments);
            args[0] = _mapError(args[0]);
            cb.apply(null, args);
        };
    }

    function stat(path, callback) {
        fs.stat(path, function(err, stats) {
            if (err){
                callback(_mapError(err));
                return;
            }

            var mtime = new Date(stats.mtime);

            var options = {
                isFile: stats.isFile(),
                mtime: mtime,
                size: stats.size,
                // TODO: figure out how to deal with realPath
                realPath: path,
                hash: mtime.getTime()
            };

            var fsStats = new FileSystemStats(options);

            callback(null, fsStats);
        });
    }

    function exists(path, callback) {
        fs.exists(path, function(exists) {
            callback(null, exists);
        });
    }

    function readdir(path, callback) {
        // Strip trailing slash(es), but make sure "/" still survives
        path = path.replace(/[^/]+\/*$/, '');

        fs.readdir(path, function (err, contents) {
            if (err) {
                callback(_mapError(err));
                return;
            }

            var count = contents.length;
            if (!count) {
                callback(null, [], []);
                return;
            }

            var stats = [];
            contents.forEach(function (val, idx) {
                stat(Path.join(path, val), function (err, stat) {
                    stats[idx] = err || stat;
                    count--;
                    if (count <= 0) {
                        callback(null, contents, stats);
                    }
                });
            });
        });
    }

    function mkdir(path, mode, callback) {
        if(typeof mode === 'function') {
            callback = mode;
        }

        fs.mkdir(path, mode, function (err) {
            if (err) {
                callback(_mapError(err));
                return;
            }
            stat(path, callback);
        });
    }

    function rename(oldPath, newPath, callback) {
        fs.rename(oldPath, newPath, _wrap(callback));
    }

    function readFile(path, options, callback) {
        if(typeof options === 'function') {
            callback = options;
        }
        options = options || {};

        var encoding = options.encoding || "utf8";

        // Execute the read and stat calls in parallel. Callback early if the
        // read call completes first with an error; otherwise wait for both
        // to finish.
        var done = false, data, stat, err;

        if (options.stat) {
            done = true;
            stat = options.stat;
        } else {
            exports.stat(path, function (_err, _stat) {
                if (done) {
                    callback(_err, _err ? null : data, _stat);
                } else {
                    done = true;
                    stat = _stat;
                    err = _err;
                }
            });
        }

        fs.readFile(path, encoding, function (_err, _data) {
            if (_err) {
                callback(_mapError(_err));
                return;
            }

            if (done) {
                callback(err, err ? null : _data, stat);
            } else {
                done = true;
                data = _data;
            }
        });
    }

    function writeFile(path, data, options, callback) {
        if(typeof options === 'function') {
            callback = options;
        }
        options = options || {};

        var encoding = options.encoding || "utf8";

        function _finishWrite(created) {
            fs.writeFile(path, data, encoding, function (err) {
                if (err) {
                    callback(_mapError(err));
                    return;
                }
                stat(path, function (err, stat) {
                    callback(err, stat, created);
                });
            });
        }

        stat(path, function (err, stats) {
            if (err) {
                switch (err) {
                case FileSystemError.NOT_FOUND:
                    _finishWrite(true);
                    break;
                default:
                    callback(err);
                }
                return;
            }

            if (options.hasOwnProperty("expectedHash") && options.expectedHash !== stats._hash) {
                console.error("Blind write attempted: ", path, stats._hash, options.expectedHash);

                if (options.hasOwnProperty("expectedContents")) {
                    fs.readFile(path, encoding, function (_err, _data) {
                        if (_err || _data !== options.expectedContents) {
                            callback(FileSystemError.CONTENTS_MODIFIED);
                            return;
                        }

                        _finishWrite(false);
                    });
                    return;
                } else {
                    callback(FileSystemError.CONTENTS_MODIFIED);
                    return;
                }
            }

            _finishWrite(false);
        });
    }

    function unlink(path, callback) {
        fs.unlink(path, function(err){
            callback(_mapError(err));
        });
    }

    function moveToTrash(path, callback) {
        // TODO: do we want to support a .trash/ dir or the like?
        unlink(path, callback);
    }

    function initWatchers(changeCallback, offlineCallback) {
        _changeCallback = changeCallback;
    }

    function watchPath(path, callback) {
        // Strip trailing slash on pathname (probably /brackets/)
        path = path.replace(/\/$/, '');
        if(watchers[path]) {
            return;
        }
        watchers[path] = fs.watch(path, {recursive: true}, function(event, filename) {
            stat(filename, function(err, stats) {
              if(err) {
                  return;
              }
              _changeCallback(filename, stats);
            });
        });
        callback();
    }

    function unwatchPath(path, callback) {
        if(watchers[path]) {
            watchers[path].close();
            delete watchers[path];
        }
        callback();
    }

    function unwatchAll(callback) {
        Object.keys(watchers).forEach(function(path) {
            unwatchPath(path, function(){});
        });
        callback();
    }

    // Export public API
    exports.showOpenDialog  = showOpenDialog;
    exports.showSaveDialog  = showSaveDialog;
    exports.exists          = exists;
    exports.readdir         = readdir;
    exports.mkdir           = mkdir;
    exports.rename          = rename;
    exports.stat            = stat;
    exports.readFile        = readFile;
    exports.writeFile       = writeFile;
    exports.unlink          = unlink;
    exports.moveToTrash     = moveToTrash;
    exports.initWatchers    = initWatchers;
    exports.watchPath       = watchPath;
    exports.unwatchPath     = unwatchPath;
    exports.unwatchAll      = unwatchAll;

    exports.recursiveWatch    = true;
    exports.normalizeUNCPaths = false;
});
<commit_msg>Fix how trailing slashes are removed from dir names<commit_after>/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
/*global define, appshell, $, window */

define(function (require, exports, module) {
    "use strict";

    var FileSystemError = require("filesystem/FileSystemError"),
        FileSystemStats = require("filesystem/FileSystemStats"),
        Dialogs         = require("widgets/Dialogs"),
        DefaultDialogs  = require("widgets/DefaultDialogs"),
        // TODO: we have to figure out how we're going to build/deploy makedrive.js, this is hacky.
        MakeDrive       = require("thirdparty/makedrive/client/dist/makedrive"),
        OpenDialog      = require("filesystem/impls/makedrive/open-dialog");

    var fs              = MakeDrive.fs(),
        Path            = MakeDrive.Path,
        watchers        = {};

    var _changeCallback;            // Callback to notify FileSystem of watcher changes

    // Give extensions access to MakeDrive's sync functionality. The hosting app
    // needs to call sync.connect(serverURL) when the user is logged in, for example.
    appshell.MakeDrive = MakeDrive;

    // TODO: Maybe use an XHR or something else other than this?
    $.get( "http://localhost:9090/api/sync", function( data ) {
      fs.sync.connect('ws://localhost:9090', data);
    });

    var sync = fs.sync;

    //TODO: Do we want to do anything other than console.log for all these events?
    sync.on('syncing', function() {
        console.log('sync started');
    });
    sync.on('error', function(e) {
        console.log('sync error: ', e);
    });
    sync.on('completed', function() {
        console.log('sync completed');
    });
    sync.on('updates', function() {
        console.log('server has updates');
    });

    // TODO: Figure out when is the best time to start the sync.
    var DocumentManager = brackets.getModule('document/DocumentManager');
    $(DocumentManager).on("documentSaved", function(err, e) {
        sync.request('/' + e.file._path);
    });

    function showOpenDialog(allowMultipleSelection, chooseDirectories, title, initialPath, fileTypes, callback) {
        OpenDialog.showOpenDialog.apply(null, arguments);
    }

    function showSaveDialog(title, initialPath, defaultName, callback) {
        var selectedPath;
        var saveResponse = window.prompt(title, defaultName);
        if(saveResponse){
            initialPath = initialPath || '/';
            selectedPath = initialPath + saveResponse;
            callback(null, selectedPath);
        }
        else{
            callback();
        }
    }

    function stripTrailingSlash(path) {
        // Strip trailing slash(es), but make sure "/" still survives
        path = path.replace(/\/+$/, '');
        return path || '/';
    }

    /**
     * Convert Filer error codes to FileSystemError values.
     *
     * @param {?number} err A Filer error code
     * @return {?string} A FileSystemError string, or null if there was no error code.
     * @private
     **/
    function _mapError(err) {
        if (!err) {
            return null;
        }

        switch (err.code) {
        case 'EINVAL':
            return FileSystemError.INVALID_PARAMS;
        case 'ENOENT':
            return FileSystemError.NOT_FOUND;
        case 'EROFS':
            return FileSystemError.NOT_WRITABLE;
        case 'ENOSPC':
            return FileSystemError.OUT_OF_SPACE;
        case 'ENOTEMPTY':
        case 'EEXIST':
            return FileSystemError.ALREADY_EXISTS;
        case 'ENOTDIR':
            return FileSystemError.INVALID_PARAMS;
        case 'EBADF':
            return FileSystemError.NOT_READABLE;
        }

        return FileSystemError.UNKNOWN;
    }

    /**
     * Convert a callback to one that transforms its first parameter from a
     * Filer error code to a FileSystemError string.
     *
     * @param {function(?number)} cb A callback that expects an Filer error code
     * @return {function(?string)} A callback that expects a FileSystemError string
     * @private
     **/
    function _wrap(cb) {
        return function (err) {
            var args = Array.prototype.slice.call(arguments);
            args[0] = _mapError(args[0]);
            cb.apply(null, args);
        };
    }

    function stat(path, callback) {
        fs.stat(path, function(err, stats) {
            if (err){
                callback(_mapError(err));
                return;
            }

            var mtime = new Date(stats.mtime);

            var options = {
                isFile: stats.isFile(),
                mtime: mtime,
                size: stats.size,
                // TODO: figure out how to deal with realPath
                realPath: path,
                hash: mtime.getTime()
            };

            var fsStats = new FileSystemStats(options);

            callback(null, fsStats);
        });
    }

    function exists(path, callback) {
        fs.exists(path, function(exists) {
            callback(null, exists);
        });
    }

    function readdir(path, callback) {
        path = stripTrailingSlash(path);

        fs.readdir(path, function (err, contents) {
            if (err) {
                callback(_mapError(err));
                return;
            }

            var count = contents.length;
            if (!count) {
                callback(null, [], []);
                return;
            }

            var stats = [];
            contents.forEach(function (val, idx) {
                stat(Path.join(path, val), function (err, stat) {
                    stats[idx] = err || stat;
                    count--;
                    if (count <= 0) {
                        callback(null, contents, stats);
                    }
                });
            });
        });
    }

    function mkdir(path, mode, callback) {
        if(typeof mode === 'function') {
            callback = mode;
        }

        fs.mkdir(path, mode, function (err) {
            if (err) {
                callback(_mapError(err));
                return;
            }
            stat(path, callback);
        });
    }

    function rename(oldPath, newPath, callback) {
        fs.rename(oldPath, newPath, _wrap(callback));
    }

    function readFile(path, options, callback) {
        if(typeof options === 'function') {
            callback = options;
        }
        options = options || {};

        var encoding = options.encoding || "utf8";

        // Execute the read and stat calls in parallel. Callback early if the
        // read call completes first with an error; otherwise wait for both
        // to finish.
        var done = false, data, stat, err;

        if (options.stat) {
            done = true;
            stat = options.stat;
        } else {
            exports.stat(path, function (_err, _stat) {
                if (done) {
                    callback(_err, _err ? null : data, _stat);
                } else {
                    done = true;
                    stat = _stat;
                    err = _err;
                }
            });
        }

        fs.readFile(path, encoding, function (_err, _data) {
            if (_err) {
                callback(_mapError(_err));
                return;
            }

            if (done) {
                callback(err, err ? null : _data, stat);
            } else {
                done = true;
                data = _data;
            }
        });
    }

    function writeFile(path, data, options, callback) {
        if(typeof options === 'function') {
            callback = options;
        }
        options = options || {};

        var encoding = options.encoding || "utf8";

        function _finishWrite(created) {
            fs.writeFile(path, data, encoding, function (err) {
                if (err) {
                    callback(_mapError(err));
                    return;
                }
                stat(path, function (err, stat) {
                    callback(err, stat, created);
                });
            });
        }

        stat(path, function (err, stats) {
            if (err) {
                switch (err) {
                case FileSystemError.NOT_FOUND:
                    _finishWrite(true);
                    break;
                default:
                    callback(err);
                }
                return;
            }

            if (options.hasOwnProperty("expectedHash") && options.expectedHash !== stats._hash) {
                console.error("Blind write attempted: ", path, stats._hash, options.expectedHash);

                if (options.hasOwnProperty("expectedContents")) {
                    fs.readFile(path, encoding, function (_err, _data) {
                        if (_err || _data !== options.expectedContents) {
                            callback(FileSystemError.CONTENTS_MODIFIED);
                            return;
                        }

                        _finishWrite(false);
                    });
                    return;
                } else {
                    callback(FileSystemError.CONTENTS_MODIFIED);
                    return;
                }
            }

            _finishWrite(false);
        });
    }

    function unlink(path, callback) {
        fs.unlink(path, function(err){
            callback(_mapError(err));
        });
    }

    function moveToTrash(path, callback) {
        // TODO: do we want to support a .trash/ dir or the like?
        unlink(path, callback);
    }

    function initWatchers(changeCallback, offlineCallback) {
        _changeCallback = changeCallback;
    }

    function watchPath(path, callback) {
        path = stripTrailingSlash(path);

        if(watchers[path]) {
            return;
        }
        watchers[path] = fs.watch(path, {recursive: true}, function(event, filename) {
            stat(filename, function(err, stats) {
              if(err) {
                  return;
              }
              _changeCallback(filename, stats);
            });
        });
        callback();
    }

    function unwatchPath(path, callback) {
        path = stripTrailingSlash(path);

        if(watchers[path]) {
            watchers[path].close();
            delete watchers[path];
        }
        callback();
    }

    function unwatchAll(callback) {
        Object.keys(watchers).forEach(function(path) {
            unwatchPath(path, function(){});
        });
        callback();
    }

    // Export public API
    exports.showOpenDialog  = showOpenDialog;
    exports.showSaveDialog  = showSaveDialog;
    exports.exists          = exists;
    exports.readdir         = readdir;
    exports.mkdir           = mkdir;
    exports.rename          = rename;
    exports.stat            = stat;
    exports.readFile        = readFile;
    exports.writeFile       = writeFile;
    exports.unlink          = unlink;
    exports.moveToTrash     = moveToTrash;
    exports.initWatchers    = initWatchers;
    exports.watchPath       = watchPath;
    exports.unwatchPath     = unwatchPath;
    exports.unwatchAll      = unwatchAll;

    exports.recursiveWatch    = true;
    exports.normalizeUNCPaths = false;
});
<|endoftext|>


<commit_before>"use strict";

const path    = require('path')
const home    = require('os-homedir')()

const express = require('express')
const log     = require('npmlog')
const gm      = require('gm').subClass({ imageMagick: true })

let tidy = {}

tidy.root = path.join(__filename, '../..')

tidy.version = '0.0.1'
log.info('Running Tidy ' + tidy.version + ' at ' + tidy.root)

tidy.config = {
  base: path.join(home, 'Pictures/TidyLibrary')
}

tidy.config.database = {
  dialect: 'sqlite3',
  connection: {
    filename: path.join(tidy.config.base, 'database.sqlite3')
  }
}

class AlbumDecorator {
  constructor(album) {
    this.album = album
  }

  get id() {
    return this.album['id']
  }

  get name() {
    return this.album['path']
  }

  get url() {
    return `/albums/${this.id}`
  }
}

class ItemDecorator {
  constructor(item) {
    this.item = item
  }

  get id() {
    return this.item['id']
  }

  get url() {
    return `/items/${this.id}`
  }

  get thumbnailUrl() {
    return `/items/${this.id}/thumb`
  }

  get fullUrl() {
    return `/items/${this.id}/full`
  }

  get originalPath() {
    return path.join(tidy.config.base, 'Originals', this.item['path'], this.item['filename'])
  }

  get thumbnailPath() {
    if (this.item['thumbnail_filename'])
    {
      return path.join(tidy.config.base, 'Thumbnails', this.item['path'], this.item['thumbnail_filename'])
    }
  }
}

const db = require('knex')(tidy.config.database)

let app = express()
app.locals.pretty = true
app.use(express.static('public'))
app.set('view engine', 'jade')

app.get('/', function(req, res) {
  let albums = []

  return db.select('*').from('albums')
    .map(function(album) {
      return new AlbumDecorator(album)
    })
    .then(function(albums) {
      res.render('index', {
        albums: albums
      });
    });
})

app.get('/albums/:id', function(req, res) {
  return db.select('*').from('albums').where({ id: req.params.id })
    .then(function(albums) {
      const album = new AlbumDecorator(albums[0])

      return db.select('*').from('items').where({ album_id: album.id })
        .map(function(item) {
          return new ItemDecorator(item)
        })
        .then(function(items) {
          res.render('album', {
            album: album,
            items: items
          })
        })
    })
})

app.get('/items/:id', function(req, res) {
  return db.select('*').from('items').where({ id: req.params.id })
    .then(function(items) {
      const item = new ItemDecorator(items[0])

      res.render('item', {
        item: item
      })
    })
})

app.get('/items/:id/:format', function(req, res) {
  return db.select('*').from('items').where({ id: req.params.id })
    .then(function(items) {
      const item = new ItemDecorator(items[0])

      if (req.params.format == 'original') {
        res.sendFile(item.originalPath, {})
      } else if (req.params.format == 'full') {
        const width  = req.query.width || 1000
        const height = req.query.height || 1000
        gm(item.originalPath)
          .autoOrient()
          .noProfile()
          .resize(width, height, '^')
          .interlace('plane')
          .quality(100)
          .stream('jpeg')
          .pipe(res)
      } else {
        if (item.thumbnailPath) {
          res.sendFile(item.thumbnailPath, {})
        } else {
          res.status(404).send('Thumbnail not created')
        }
      }
    })
})

function startServer() {
  app.listen(3000, function() {
    log.info("Listening on port 3000")
  })
}

exports.run = function() {
  db.migrate.latest({
    database:  tidy.config.database,
    directory: path.join(tidy.root, 'migrations')
  }).then(startServer)
}
<commit_msg>Add unsharp to full preview<commit_after>"use strict";

const path    = require('path')
const home    = require('os-homedir')()

const express = require('express')
const log     = require('npmlog')
const gm      = require('gm').subClass({ imageMagick: true })

let tidy = {}

tidy.root = path.join(__filename, '../..')

tidy.version = '0.0.1'
log.info('Running Tidy ' + tidy.version + ' at ' + tidy.root)

tidy.config = {
  base: path.join(home, 'Pictures/TidyLibrary')
}

tidy.config.database = {
  dialect: 'sqlite3',
  connection: {
    filename: path.join(tidy.config.base, 'database.sqlite3')
  }
}

class AlbumDecorator {
  constructor(album) {
    this.album = album
  }

  get id() {
    return this.album['id']
  }

  get name() {
    return this.album['path']
  }

  get url() {
    return `/albums/${this.id}`
  }
}

class ItemDecorator {
  constructor(item) {
    this.item = item
  }

  get id() {
    return this.item['id']
  }

  get url() {
    return `/items/${this.id}`
  }

  get thumbnailUrl() {
    return `/items/${this.id}/thumb`
  }

  get fullUrl() {
    return `/items/${this.id}/full`
  }

  get originalPath() {
    return path.join(tidy.config.base, 'Originals', this.item['path'], this.item['filename'])
  }

  get thumbnailPath() {
    if (this.item['thumbnail_filename'])
    {
      return path.join(tidy.config.base, 'Thumbnails', this.item['path'], this.item['thumbnail_filename'])
    }
  }
}

const db = require('knex')(tidy.config.database)

let app = express()
app.locals.pretty = true
app.use(express.static('public'))
app.set('view engine', 'jade')

app.get('/', function(req, res) {
  let albums = []

  return db.select('*').from('albums')
    .map(function(album) {
      return new AlbumDecorator(album)
    })
    .then(function(albums) {
      res.render('index', {
        albums: albums
      });
    });
})

app.get('/albums/:id', function(req, res) {
  return db.select('*').from('albums').where({ id: req.params.id })
    .then(function(albums) {
      const album = new AlbumDecorator(albums[0])

      return db.select('*').from('items').where({ album_id: album.id })
        .map(function(item) {
          return new ItemDecorator(item)
        })
        .then(function(items) {
          res.render('album', {
            album: album,
            items: items
          })
        })
    })
})

app.get('/items/:id', function(req, res) {
  return db.select('*').from('items').where({ id: req.params.id })
    .then(function(items) {
      const item = new ItemDecorator(items[0])

      res.render('item', {
        item: item
      })
    })
})

app.get('/items/:id/:format', function(req, res) {
  return db.select('*').from('items').where({ id: req.params.id })
    .then(function(items) {
      const item = new ItemDecorator(items[0])

      if (req.params.format == 'original') {
        res.sendFile(item.originalPath, {})
      } else if (req.params.format == 'full') {
        const width  = req.query.width || 1000
        const height = req.query.height || 1000
        gm(item.originalPath)
          .autoOrient()
          .noProfile()
          .resize(width, height, '^')
          .unsharp(0.5)
          .interlace('plane')
          .quality(100)
          .stream('jpeg')
          .pipe(res)
      } else {
        if (item.thumbnailPath) {
          res.sendFile(item.thumbnailPath, {})
        } else {
          res.status(404).send('Thumbnail not created')
        }
      }
    })
})

function startServer() {
  app.listen(3000, function() {
    log.info("Listening on port 3000")
  })
}

exports.run = function() {
  db.migrate.latest({
    database:  tidy.config.database,
    directory: path.join(tidy.root, 'migrations')
  }).then(startServer)
}
<|endoftext|>


<commit_before>'use strict';
import React from 'react';
import moment from 'moment';
import { sortListByDate } from './helpers/sort';

/**
 * Method to render the publication status of a given GDM's classification
 * @param {array} snapshots - List of snapshots associated with classification
 */
export function renderPublishStatus(snapshots) {
    const sortedSnapshots = snapshots && snapshots.length ? sortListByDate(snapshots, 'date_created') : [];
    // Get any snapshots that had been published
    const publishedSnapshots = sortedSnapshots.filter(snapshot => {
        return (snapshot.resource && snapshot.resource.publishClassification) || snapshot.publishStatus;
    });
    // Get any snapshots that had been approved but not published
    const approvedSnapshots = sortedSnapshots.filter(snapshot => {
        return snapshot.approvalStatus === 'Approved' && ((snapshot.resource && !snapshot.resource.publishClassification) || !snapshot.publishStatus);
    });
    // If the current approved Classification is more recent than this published Classification, show warning message
    let publishedWarningMessage = false, publishDate;
    if (approvedSnapshots && approvedSnapshots.length && publishedSnapshots && publishedSnapshots.length) {
        // The 'resource' object was absent in the flatten 'snapshot' object prior to R22 release.
        // So for those snapshots saved into 'associatedClassificationSnapshots' array previously,
        // comparing 'approvalDate' to 'publishDate' is impossible due to the absence of 'resource' obejct.
        // Going forward, we still want the 'approvalDate' to 'publishDate' comparison because it's more accurate.
        if (approvedSnapshots[0].resource && approvedSnapshots[0].resource.approvalDate && publishedSnapshots[0].resource && publishedSnapshots[0].resource.publishDate) {
            publishedWarningMessage = moment(approvedSnapshots[0].resource.approvalDate).isAfter(publishedSnapshots[0].resource.publishDate);
            publishDate = publishedSnapshots[0].resource.publishDate;
        } else {
            // For snapshots saved into 'associatedClassificationSnapshots' array prior to R22 release,
            // we fallback to compare their 'date_created' timestamps - current approved vs. previously approved/published
            publishedWarningMessage = moment(approvedSnapshots[0].date_created).isAfter(publishedSnapshots[0].date_created);
        }
    }

    if (publishedSnapshots && publishedSnapshots.length > 0) {
        return (

                {publishDate ?

                        PUBLISHED

                    :
                    PUBLISHED
                }
                {publishedWarningMessage ? renderPublishedWarningMessage() : null}

        );
    } else {
        return null;
    }
}

function renderPublishedWarningMessage() {
    return (

    );
}<commit_msg>:bug: Fixed bug in which tooltip bubble fails to show upon mouseover the 'PUBLISHED' label<commit_after>'use strict';
import React from 'react';
import moment from 'moment';
import { sortListByDate } from './helpers/sort';

/**
 * Method to render the publication status of a given GDM's classification
 * @param {array} snapshots - List of snapshots associated with classification
 */
export function renderPublishStatus(snapshots) {
    const sortedSnapshots = snapshots && snapshots.length ? sortListByDate(snapshots, 'date_created') : [];
    // Get any snapshots that had been published
    const publishedSnapshots = sortedSnapshots.filter(snapshot => {
        return (snapshot.resource && snapshot.resource.publishClassification) || snapshot.publishStatus;
    });
    // Get any snapshots that had been approved but not published
    const approvedSnapshots = sortedSnapshots.filter(snapshot => {
        return snapshot.approvalStatus === 'Approved' && ((snapshot.resource && !snapshot.resource.publishClassification) || !snapshot.publishStatus);
    });
    // If the current approved Classification is more recent than this published Classification, show warning message
    let publishedWarningMessage = false;
    if (approvedSnapshots && approvedSnapshots.length && publishedSnapshots && publishedSnapshots.length) {
        // The 'resource' object was absent in the flatten 'snapshot' object prior to R22 release.
        // So for those snapshots saved into 'associatedClassificationSnapshots' array previously,
        // comparing 'approvalDate' to 'publishDate' is impossible due to the absence of 'resource' obejct.
        // Going forward, we still want the 'approvalDate' to 'publishDate' comparison because it's more accurate.
        if (approvedSnapshots[0].resource && approvedSnapshots[0].resource.approvalDate && publishedSnapshots[0].resource && publishedSnapshots[0].resource.publishDate) {
            publishedWarningMessage = moment(approvedSnapshots[0].resource.approvalDate).isAfter(publishedSnapshots[0].resource.publishDate);
        } else {
            // For snapshots saved into 'associatedClassificationSnapshots' array prior to R22 release,
            // we fallback to compare their 'date_created' timestamps - current approved vs. previously approved/published
            publishedWarningMessage = moment(approvedSnapshots[0].date_created).isAfter(publishedSnapshots[0].date_created);
        }
    }

    if (publishedSnapshots && publishedSnapshots.length) {
        let publishDate = publishedSnapshots[0].resource && publishedSnapshots[0].resource.publishDate ? publishedSnapshots[0].resource.publishDate : null;
        return (

                {publishDate ?

                        PUBLISHED

                    :
                    PUBLISHED
                }
                {publishedWarningMessage ? renderPublishedWarningMessage() : null}

        );
    } else {
        return null;
    }
}

function renderPublishedWarningMessage() {
    return (

    );
}<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.notification.email',
  name: 'SMTPEmailService',

  implements: [
    'foam.core.ContextAgent',
    'foam.nanos.notification.email.EmailService',
  ],

  documentation: 'Implementation of Email Service using SMTP',

  imports: [
    'threadPool?'
  ],

  javaImports: [
    'foam.core.ContextAgent',
    'foam.core.X',
    'foam.nanos.pool.FixedThreadPool',
    'foam.util.SafetyUtil',
    'java.nio.charset.StandardCharsets',
    'java.util.Date',
    'java.util.Properties',
    'java.util.List',
    'javax.mail.*',
    'javax.mail.internet.InternetAddress',
    'javax.mail.internet.MimeMessage',
    'org.apache.commons.lang3.StringUtils',
    'org.jtwig.JtwigTemplate',
    'org.jtwig.resource.loader.TypedResourceLoader',
    'foam.dao.ArraySink',
    'foam.dao.DAO',
    'foam.nanos.auth.User',
    'foam.nanos.auth.Group',
    'foam.nanos.logger.Logger',
    'foam.nanos.om.OMLogger',
    'static foam.mlang.MLang.EQ'
  ],

  axioms: [
    {
      name: 'javaExtras',
      buildJavaClass: function(cls) {
        cls.extras.push(foam.java.Code.create({
          data:
            `private class SMTPAuthenticator extends javax.mail.Authenticator {
              protected String username_;
              protected String password_;

              public SMTPAuthenticator(String username, String password) {
                this.username_ = username;
                this.password_ = password;
              }

              @Override
              protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(this.username_, this.password_);
              }
            }
            `
        }));
      }
    }
  ],

  properties: [
    {
      name: 'session_',
      javaType: 'Session',
      class: 'Object',
      javaFactory:
      `
        Properties props = new Properties();
        props.setProperty("mail.smtp.auth", getAuthenticate() ? "true" : "false");
        props.setProperty("mail.smtp.starttls.enable", getStarttls() ? "true" : "false");
        props.setProperty("mail.smtp.host", getHost());
        props.setProperty("mail.smtp.port", getPort());
        if ( getAuthenticate() ) {
          return Session.getInstance(props, new SMTPAuthenticator(getUsername(), getPassword()));
        }
        return Session.getInstance(props);
      `
    },
    {
      class: 'Object',
      javaType: 'Transport',
      name: 'transport_',
      javaFactory:
      `
        Logger logger = (Logger) getX().get("logger");
        Transport transport = null;
        try {
          transport = getSession_().getTransport("smtp");
          transport.connect(getUsername(), getPassword());
          logger.info("SMTPEmailService connected.");
        } catch ( Exception e ) {
          logger.error("Transport failed to initialize: " + e);
        }
        return transport;
      `
    },
    {
      class: 'String',
      name: 'host',
      value: '127.0.0.1'
    },
    {
      class: 'String',
      name: 'port',
      value: '25'
    },
    {
      class: 'Boolean',
      name: 'authenticate',
      value: false
    },
    {
      class: 'Boolean',
      name: 'starttls',
      value: false
    },
    {
      class: 'String',
      name: 'username',
      value: null
    },
    {
      class: 'String',
      name: 'password',
      value: null
    }
  ],

  methods: [
    {
      name: 'createMimeMessage',
      javaType: 'MimeMessage',
      documentation: `Create a MimeMessage from the passed EmailMessage`,
      args: [
        {
          name: 'emailMessage',
          type: 'foam.nanos.notification.email.EmailMessage'
        }
      ],
      javaCode:
      `
        Logger logger = (Logger) getX().get("logger");
        try {
          MimeMessage message = new MimeMessage(getSession_());

          // the From Property is mainly to hide our smtp user credetials.
          if ( emailMessage.isPropertySet("from") ) {
            if ( emailMessage.isPropertySet("displayName") ) {
              message.setFrom( new InternetAddress(emailMessage.getFrom(), emailMessage.getDisplayName()) );
            } else {
              message.setFrom(new InternetAddress(emailMessage.getFrom()));
            }
          } else if ( emailMessage.isPropertySet("replyTo") ) {
              if ( emailMessage.isPropertySet("displayName") ) {
                message.setFrom( new InternetAddress(emailMessage.getReplyTo(), emailMessage.getDisplayName()) );
              } else {
                message.setFrom(new InternetAddress(emailMessage.getReplyTo()));
              }
          }

          if ( emailMessage.isPropertySet("replyTo") )
            message.setReplyTo(InternetAddress.parse(emailMessage.getReplyTo()));

          if ( emailMessage.isPropertySet("subject") )
            message.setSubject(emailMessage.getSubject());

          if ( emailMessage.isPropertySet("body") )
            message.setContent(emailMessage.getBody(), "text/html; charset=utf-8");

          if ( emailMessage.isPropertySet("to") ) {
            if ( emailMessage.getTo().length == 1 ) {
              message.setRecipient(Message.RecipientType.TO, new InternetAddress((emailMessage.getTo())[0], false));
            } else {
              message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(StringUtils.join(emailMessage.getTo(), ",")));
            }
          }

          if ( emailMessage.isPropertySet("cc") ) {
            if ( emailMessage.getCc().length == 1 ) {
              message.setRecipient(Message.RecipientType.CC, new InternetAddress((emailMessage.getCc())[0], false));
            } else {
              message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(StringUtils.join(emailMessage.getCc(), ",")));
            }
          }

          if ( emailMessage.isPropertySet("bcc") ) {
            if ( emailMessage.getBcc().length == 1 ) {
              message.setRecipient(Message.RecipientType.BCC, new InternetAddress((emailMessage.getBcc())[0], false));
            } else {
              message.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(StringUtils.join(emailMessage.getBcc(), ",")));
            }
          }

          message.setSentDate(new Date());
          logger.info("SMTPEmailService Created MimeMessage.");
          return message;
        } catch (Throwable t) {
          logger.error("SMTPEmailService failed to created MimeMessage. " + t);
          return null;
        }
      `
    },
    {
      name: 'sendEmail',
      javaCode: `
        emailMessage = (EmailMessage) emailMessage.fclone();
        MimeMessage message = createMimeMessage(emailMessage);
        Logger logger = (Logger) getX().get("logger");
        try {
          getTransport_().send(message);
          emailMessage.setStatus(Status.SENT);
          logger.info("SMTPEmailService sent MimeMessage.");
        } catch ( SendFailedException e ) {
          emailMessage.setStatus(Status.FAILED);
          logger.error("SMTPEmailService sending MimeMessage failed. " + e);
        } catch ( MessagingException e ) {
          try {
            getTransport_().close();
          } catch ( Exception e2 ) {
            logger.error("Failed to close transport");
          }
          clearTransport_();
          logger.error("SMTPEmailService sending MimeMessage failed. " + e);
        }
        return emailMessage;
      `
    },
    {
      name: 'execute',
      javaCode: `
        // TODO: This should be a cron job.
        DAO emailMessageDAO = (DAO) x.get("emailMessageDAO");
        List<EmailMessage> emailMessages = ((foam.dao.ArraySink)
          emailMessageDAO
            .where(EQ(EmailMessage.STATUS, Status.UNSENT))
            .select(new ArraySink()))
            .getArray();
        for ( EmailMessage emailMessage : emailMessages ) {
          emailMessageDAO.put(sendEmail(x, emailMessage));
        }
      `
    }
  ]
});
<commit_msg>Change logger to debug<commit_after>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.notification.email',
  name: 'SMTPEmailService',

  implements: [
    'foam.core.ContextAgent',
    'foam.nanos.notification.email.EmailService',
  ],

  documentation: 'Implementation of Email Service using SMTP',

  imports: [
    'threadPool?'
  ],

  javaImports: [
    'foam.core.ContextAgent',
    'foam.core.X',
    'foam.nanos.pool.FixedThreadPool',
    'foam.util.SafetyUtil',
    'java.nio.charset.StandardCharsets',
    'java.util.Date',
    'java.util.Properties',
    'java.util.List',
    'javax.mail.*',
    'javax.mail.internet.InternetAddress',
    'javax.mail.internet.MimeMessage',
    'org.apache.commons.lang3.StringUtils',
    'org.jtwig.JtwigTemplate',
    'org.jtwig.resource.loader.TypedResourceLoader',
    'foam.dao.ArraySink',
    'foam.dao.DAO',
    'foam.nanos.auth.User',
    'foam.nanos.auth.Group',
    'foam.nanos.logger.Logger',
    'foam.nanos.om.OMLogger',
    'static foam.mlang.MLang.EQ'
  ],

  axioms: [
    {
      name: 'javaExtras',
      buildJavaClass: function(cls) {
        cls.extras.push(foam.java.Code.create({
          data:
            `private class SMTPAuthenticator extends javax.mail.Authenticator {
              protected String username_;
              protected String password_;

              public SMTPAuthenticator(String username, String password) {
                this.username_ = username;
                this.password_ = password;
              }

              @Override
              protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(this.username_, this.password_);
              }
            }
            `
        }));
      }
    }
  ],

  properties: [
    {
      name: 'session_',
      javaType: 'Session',
      class: 'Object',
      javaFactory:
      `
        Properties props = new Properties();
        props.setProperty("mail.smtp.auth", getAuthenticate() ? "true" : "false");
        props.setProperty("mail.smtp.starttls.enable", getStarttls() ? "true" : "false");
        props.setProperty("mail.smtp.host", getHost());
        props.setProperty("mail.smtp.port", getPort());
        if ( getAuthenticate() ) {
          return Session.getInstance(props, new SMTPAuthenticator(getUsername(), getPassword()));
        }
        return Session.getInstance(props);
      `
    },
    {
      class: 'Object',
      javaType: 'Transport',
      name: 'transport_',
      javaFactory:
      `
        Logger logger = (Logger) getX().get("logger");
        Transport transport = null;
        try {
          transport = getSession_().getTransport("smtp");
          transport.connect(getUsername(), getPassword());
          logger.info("SMTPEmailService connected.");
        } catch ( Exception e ) {
          logger.error("Transport failed to initialize: " + e);
        }
        return transport;
      `
    },
    {
      class: 'String',
      name: 'host',
      value: '127.0.0.1'
    },
    {
      class: 'String',
      name: 'port',
      value: '25'
    },
    {
      class: 'Boolean',
      name: 'authenticate',
      value: false
    },
    {
      class: 'Boolean',
      name: 'starttls',
      value: false
    },
    {
      class: 'String',
      name: 'username',
      value: null
    },
    {
      class: 'String',
      name: 'password',
      value: null
    }
  ],

  methods: [
    {
      name: 'createMimeMessage',
      javaType: 'MimeMessage',
      documentation: `Create a MimeMessage from the passed EmailMessage`,
      args: [
        {
          name: 'emailMessage',
          type: 'foam.nanos.notification.email.EmailMessage'
        }
      ],
      javaCode:
      `
        Logger logger = (Logger) getX().get("logger");
        try {
          MimeMessage message = new MimeMessage(getSession_());

          // the From Property is mainly to hide our smtp user credetials.
          if ( emailMessage.isPropertySet("from") ) {
            if ( emailMessage.isPropertySet("displayName") ) {
              message.setFrom( new InternetAddress(emailMessage.getFrom(), emailMessage.getDisplayName()) );
            } else {
              message.setFrom(new InternetAddress(emailMessage.getFrom()));
            }
          } else if ( emailMessage.isPropertySet("replyTo") ) {
              if ( emailMessage.isPropertySet("displayName") ) {
                message.setFrom( new InternetAddress(emailMessage.getReplyTo(), emailMessage.getDisplayName()) );
              } else {
                message.setFrom(new InternetAddress(emailMessage.getReplyTo()));
              }
          }

          if ( emailMessage.isPropertySet("replyTo") )
            message.setReplyTo(InternetAddress.parse(emailMessage.getReplyTo()));

          if ( emailMessage.isPropertySet("subject") )
            message.setSubject(emailMessage.getSubject());

          if ( emailMessage.isPropertySet("body") )
            message.setContent(emailMessage.getBody(), "text/html; charset=utf-8");

          if ( emailMessage.isPropertySet("to") ) {
            if ( emailMessage.getTo().length == 1 ) {
              message.setRecipient(Message.RecipientType.TO, new InternetAddress((emailMessage.getTo())[0], false));
            } else {
              message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(StringUtils.join(emailMessage.getTo(), ",")));
            }
          }

          if ( emailMessage.isPropertySet("cc") ) {
            if ( emailMessage.getCc().length == 1 ) {
              message.setRecipient(Message.RecipientType.CC, new InternetAddress((emailMessage.getCc())[0], false));
            } else {
              message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(StringUtils.join(emailMessage.getCc(), ",")));
            }
          }

          if ( emailMessage.isPropertySet("bcc") ) {
            if ( emailMessage.getBcc().length == 1 ) {
              message.setRecipient(Message.RecipientType.BCC, new InternetAddress((emailMessage.getBcc())[0], false));
            } else {
              message.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(StringUtils.join(emailMessage.getBcc(), ",")));
            }
          }

          message.setSentDate(new Date());
          logger.info("SMTPEmailService Created MimeMessage.");
          return message;
        } catch (Throwable t) {
          logger.error("SMTPEmailService failed to created MimeMessage. " + t);
          return null;
        }
      `
    },
    {
      name: 'sendEmail',
      javaCode: `
        emailMessage = (EmailMessage) emailMessage.fclone();
        MimeMessage message = createMimeMessage(emailMessage);
        Logger logger = (Logger) getX().get("logger");
        try {
          getTransport_().send(message);
          emailMessage.setStatus(Status.SENT);
          logger.debug("SMTPEmailService sent MimeMessage.");
        } catch ( SendFailedException e ) {
          emailMessage.setStatus(Status.FAILED);
          logger.error("SMTPEmailService sending MimeMessage failed. " + e);
        } catch ( MessagingException e ) {
          try {
            getTransport_().close();
          } catch ( Exception e2 ) {
            logger.error("Failed to close transport");
          }
          clearTransport_();
          logger.error("SMTPEmailService sending MimeMessage failed. " + e);
        }
        return emailMessage;
      `
    },
    {
      name: 'execute',
      javaCode: `
        // TODO: This should be a cron job.
        DAO emailMessageDAO = (DAO) x.get("emailMessageDAO");
        List<EmailMessage> emailMessages = ((foam.dao.ArraySink)
          emailMessageDAO
            .where(EQ(EmailMessage.STATUS, Status.UNSENT))
            .select(new ArraySink()))
            .getArray();
        for ( EmailMessage emailMessage : emailMessages ) {
          emailMessageDAO.put(sendEmail(x, emailMessage));
        }
      `
    }
  ]
});
<|endoftext|>


<commit_before>/**
* @module muttrpod/server
*/

'use strict';

var http = require('http');
var https = require('https');
var muttr = require('muttr');
var ws = require('ws');
var fs = require('fs');
var express = require('express');
var async = require('async');
var assert = require('assert');
var events = require('events');
var util = require('util');
var merge = require('merge');
var mongoose = require('mongoose');

var DHTStorageAdapter = require('./storage');
var Logger = require('./logger');
var Router = require('./router');
var Bus = require('./bus');

var favicon = require('serve-favicon');
var rawbody = require('./middlewares/rawbody');
var forceSSL = require('./middlewares/forcessl');

util.inherits(Server, events.EventEmitter);

/**
* Creates a MuttrPod server
* @constructor
* @param {object} config
*/
function Server(config) {
  if (!(this instanceof Server)) {
    return new Server(config);
  }

  events.EventEmitter.call(this);

  this._log = new Logger(config.verbosity);
  this.config = this._loadConfig(config);
}

/**
* Starts the MuttrPod server
* #start
* @param {function} onReady
*/
Server.prototype.start = function(onReady) {
  var self = this;

  if (typeof onReady === 'function') {
    this.once('ready', onReady);
    this.once('error', onReady);
  }

  var initializers = [
    this._connectStorage.bind(this),
    this._joinNetwork.bind(this),
    this._configureApp.bind(this),
    this._startServer.bind(this),
    this._startRedirector.bind(this)
  ];

  async.series(initializers, function(err) {
    if (err) {
      self._log.error(err.message);
      return self.emit('error', err);
    }

    self.emit('ready');
  });
};

/**
* Validates and sets config
* #_loadConfig
* @param {object} config
*/
Server.prototype._loadConfig = function(config) {
  if (config.promiscuous) {
    process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
  }

  return config;
};

/**
* Opens database connection
* #_connectStorage
* @param {function} callback
*/
Server.prototype._connectStorage = function(callback) {
  var self = this;
  var options = {
    user: this.config.storage.user,
    pass: this.config.storage.pass
  };

  var uris = this.config.storage.nodes.map(function(node) {
    var protocol = 'mongodb://';
    var uri = node.host + ':' + node.port;
    var path = '/' + self.config.storage.name;

    return protocol + uri + path;
  });

  this.storage = mongoose.connect(uris.join(), options, function(err) {
    if (err) {
      return callback(err);
    }

    self._log.info('connected to database: %s', self.config.storage.name);
    callback();
  });
};

/**
* Joins the Muttr DHT
* #_joinNetwork
* @param {function} callback
*/
Server.prototype._joinNetwork = function(callback) {
  var storage = new DHTStorageAdapter(this.storage);
  var options = merge({ storage: storage }, this.config.network);

  this.dht = new muttr.Connection(options);

  this.dht.open();
  this._log.info('accepting udp connections on port: %s', options.port);

  callback();
};

/**
* Starts HTTP(S) and WS servers
* #_configureApp
* @param {function} callback
*/
Server.prototype._configureApp = function(callback) {
  this._app = express();

  this._app.set('x-powered-by', false);
  this._app.use(favicon(__dirname + '/../www/img/muttr-logo.png'));
  this._app.use(express.static(__dirname + '/../www'));
  this._app.use(rawbody);

  callback();
};

/**
* Starts HTTP(S) and WS servers
* #_startServer
* @param {function} callback
*/
Server.prototype._startServer = function(callback) {
  var self = this;
  var WSServer = ws.Server;
  var useSSL = this.config.server.ssl;
  var address = this.config.server.address;
  var port = this.config.server.port;

  if (useSSL) {
    this._server = https.createServer({
      ca: this.config.server.ca.map(function(path) {
        return fs.readFileSync(path);
      }),
      key: fs.readFileSync(this.config.server.key),
      cert: fs.readFileSync(this.config.server.cert),
      requestCert: false,
      rejectUnauthorized: false
    }, this._app);
  } else {
    this._server = http.createServer(this._app);
  }

  this._wsserver = new WSServer({ server: this._server });
  this._bus = new Bus({ wsserver: this._wsserver, logger: this._log });
  this._router = Router().mount(this);

  this._server.listen(port, address, function(err) {
    if (err) {
      return callback(err);
    }

    self._log.info('http(s) and ws(s) server listening on port: %s', port);
    callback();
  });
};

/**
* Starts HTTP redirector to HTTPS if enbled
* #_startRedirector
* @param {function} callback
*/
Server.prototype._startRedirector = function(callback) {
  var self = this;
  var address = this.config.server.address;
  var port = this.config.server.redirect;

  if (!this.config.server.redirect) {
    return callback();
  }

  this._redirector = http.createServer(express().use(forceSSL(this.config)));

  this._redirector.listen(port, address, function(err) {
    if (err) {
      return callback(err);
    }

    self._log.info('redirecting from port: %s', self.config.server.redirect);
    callback();
  });
};

module.exports = Server;
<commit_msg>update log statement<commit_after>/**
* @module muttrpod/server
*/

'use strict';

var http = require('http');
var https = require('https');
var muttr = require('muttr');
var ws = require('ws');
var fs = require('fs');
var express = require('express');
var async = require('async');
var assert = require('assert');
var events = require('events');
var util = require('util');
var merge = require('merge');
var mongoose = require('mongoose');

var DHTStorageAdapter = require('./storage');
var Logger = require('./logger');
var Router = require('./router');
var Bus = require('./bus');

var favicon = require('serve-favicon');
var rawbody = require('./middlewares/rawbody');
var forceSSL = require('./middlewares/forcessl');

util.inherits(Server, events.EventEmitter);

/**
* Creates a MuttrPod server
* @constructor
* @param {object} config
*/
function Server(config) {
  if (!(this instanceof Server)) {
    return new Server(config);
  }

  events.EventEmitter.call(this);

  this._log = new Logger(config.verbosity);
  this.config = this._loadConfig(config);
}

/**
* Starts the MuttrPod server
* #start
* @param {function} onReady
*/
Server.prototype.start = function(onReady) {
  var self = this;

  if (typeof onReady === 'function') {
    this.once('ready', onReady);
    this.once('error', onReady);
  }

  var initializers = [
    this._connectStorage.bind(this),
    this._joinNetwork.bind(this),
    this._configureApp.bind(this),
    this._startServer.bind(this),
    this._startRedirector.bind(this)
  ];

  async.series(initializers, function(err) {
    if (err) {
      self._log.error(err.message);
      return self.emit('error', err);
    }

    self.emit('ready');
  });
};

/**
* Validates and sets config
* #_loadConfig
* @param {object} config
*/
Server.prototype._loadConfig = function(config) {
  if (config.promiscuous) {
    process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
  }

  return config;
};

/**
* Opens database connection
* #_connectStorage
* @param {function} callback
*/
Server.prototype._connectStorage = function(callback) {
  var self = this;
  var options = {
    user: this.config.storage.user,
    pass: this.config.storage.pass
  };

  var uris = this.config.storage.nodes.map(function(node) {
    var protocol = 'mongodb://';
    var uri = node.host + ':' + node.port;
    var path = '/' + self.config.storage.name;

    return protocol + uri + path;
  });

  this.storage = mongoose.connect(uris.join(), options, function(err) {
    if (err) {
      return callback(err);
    }

    self._log.info('connected to database: %s', self.config.storage.name);
    callback();
  });
};

/**
* Joins the Muttr DHT
* #_joinNetwork
* @param {function} callback
*/
Server.prototype._joinNetwork = function(callback) {
  var storage = new DHTStorageAdapter(this.storage);
  var options = merge({ storage: storage }, this.config.network);

  this.dht = new muttr.Connection(options);

  this.dht.open();
  this._log.info('accepting tcp connections on port: %s', options.port);

  callback();
};

/**
* Starts HTTP(S) and WS servers
* #_configureApp
* @param {function} callback
*/
Server.prototype._configureApp = function(callback) {
  this._app = express();

  this._app.set('x-powered-by', false);
  this._app.use(favicon(__dirname + '/../www/img/muttr-logo.png'));
  this._app.use(express.static(__dirname + '/../www'));
  this._app.use(rawbody);

  callback();
};

/**
* Starts HTTP(S) and WS servers
* #_startServer
* @param {function} callback
*/
Server.prototype._startServer = function(callback) {
  var self = this;
  var WSServer = ws.Server;
  var useSSL = this.config.server.ssl;
  var address = this.config.server.address;
  var port = this.config.server.port;

  if (useSSL) {
    this._server = https.createServer({
      ca: this.config.server.ca.map(function(path) {
        return fs.readFileSync(path);
      }),
      key: fs.readFileSync(this.config.server.key),
      cert: fs.readFileSync(this.config.server.cert),
      requestCert: false,
      rejectUnauthorized: false
    }, this._app);
  } else {
    this._server = http.createServer(this._app);
  }

  this._wsserver = new WSServer({ server: this._server });
  this._bus = new Bus({ wsserver: this._wsserver, logger: this._log });
  this._router = Router().mount(this);

  this._server.listen(port, address, function(err) {
    if (err) {
      return callback(err);
    }

    self._log.info('http(s) and ws(s) server listening on port: %s', port);
    callback();
  });
};

/**
* Starts HTTP redirector to HTTPS if enbled
* #_startRedirector
* @param {function} callback
*/
Server.prototype._startRedirector = function(callback) {
  var self = this;
  var address = this.config.server.address;
  var port = this.config.server.redirect;

  if (!this.config.server.redirect) {
    return callback();
  }

  this._redirector = http.createServer(express().use(forceSSL(this.config)));

  this._redirector.listen(port, address, function(err) {
    if (err) {
      return callback(err);
    }

    self._log.info('redirecting from port: %s', self.config.server.redirect);
    callback();
  });
};

module.exports = Server;
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.notification.email',
  name: 'SMTPEmailService',

  documentation: 'Implementation of Email Service using SMTP',

  implements: [
    'foam.nanos.NanoService',
    'foam.nanos.notification.email.EmailService'
  ],

  imports: [
    'threadPool?', // Only imported in Java
    'appConfig?'
  ],

  javaImports: [
    'foam.core.ContextAgent',
    'foam.core.X',
    'foam.nanos.pool.FixedThreadPool',
    'foam.util.SafetyUtil',
    'java.nio.charset.StandardCharsets',
    'java.util.Date',
    'java.util.Properties',
    'javax.mail.*',
    'javax.mail.internet.InternetAddress',
    'javax.mail.internet.MimeMessage',
    'org.apache.commons.lang3.StringUtils',
    'org.jtwig.environment.EnvironmentConfiguration',
    'org.jtwig.environment.EnvironmentConfigurationBuilder',
    'org.jtwig.JtwigModel',
    'org.jtwig.JtwigTemplate',
    'org.jtwig.resource.loader.TypedResourceLoader'
  ],

  axioms: [
    {
      name: 'javaExtras',
      buildJavaClass: function (cls) {
        cls.extras.push(foam.java.Code.create({
          data:
`private class SMTPAuthenticator extends javax.mail.Authenticator {
  protected String username_;
  protected String password_;

  public SMTPAuthenticator(String username, String password) {
    this.username_ = username;
    this.password_ = password;
  }

  @Override
  protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication(this.username_, this.password_);
  }
}

protected Session session_ = null;
protected EnvironmentConfiguration config_ = null;`
        }))
      }
    }
  ],

  properties: [
    {
      class: 'String',
      name: 'host',
      value: '127.0.0.1'
    },
    {
      class: 'String',
      name: 'port',
      value: '25'
    },
    {
      class: 'Boolean',
      name: 'authenticate',
      value: false
    },
    {
      class: 'Boolean',
      name: 'starttls',
      value: false
    },
    {
      class: 'String',
      name: 'username',
      value: null
    },
    {
      class: 'String',
      name: 'password',
      value: null
    },
    {
      class: 'String',
      name: 'from',
      value: null
    },
    {
      class: 'String',
      name: 'displayName',
      value: null
    },
    {
      class: 'String',
      name: 'replyTo',
      value: null
    }
  ],

  methods: [
    {
      name: 'getConfig',
      javaReturns: 'EnvironmentConfiguration',
      args: [
        {
          name: 'group',
          javaType: 'String'
        }
      ],
      javaCode:
`if ( config_ == null ) {
  config_ = EnvironmentConfigurationBuilder
    .configuration()
    .resources()
      .resourceLoaders()
        .add(new TypedResourceLoader("dao", new DAOResourceLoader(getX(), group)))
      .and()
    .and()
  .build();
}
return config_;`
    },
    {
      name: 'createMimeMessage',
      javaReturns: 'MimeMessage',
      args: [
        {
          name: 'emailMessage',
          javaType: 'foam.nanos.notification.email.EmailMessage'
        }
      ],
      javaCode:
`try {
  MimeMessage message = new MimeMessage(session_);

  // don't send email if no sender
  String from = getFrom();
  if ( SafetyUtil.isEmpty(from) )
    return null;

  // add display name if present
  String displayName = getDisplayName();
  if ( SafetyUtil.isEmpty(displayName) ) {
    message.setFrom(new InternetAddress(from));
  } else {
    message.setFrom(new InternetAddress(from, displayName));
  }

  // attach reply to if present
  String replyTo = getReplyTo();
  if ( ! SafetyUtil.isEmpty(replyTo) ) {
    message.setReplyTo(InternetAddress.parse(replyTo));
  }

  // don't send email if no subject
  String subject = emailMessage.getSubject();
  if ( SafetyUtil.isEmpty(subject) )
    return null;
  message.setSubject(subject);

  // don't send email if no body
  String body = emailMessage.getBody();
  if ( SafetyUtil.isEmpty(body) )
    return null;
  message.setContent(body, "text/html; charset=utf-8");

  // don't send email if no recipient
  String[] to = emailMessage.getTo();
  if ( to == null || to.length <= 0 )
    return null;

  if ( to.length == 1 ) {
    message.setRecipient(Message.RecipientType.TO, new InternetAddress(to[0], false));
  } else {
    message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(StringUtils.join(to, ",")));
  }

  // send email even if no CC
  String[] cc = emailMessage.getCc();
  if ( cc != null && cc.length == 1 ) {
    message.setRecipient(Message.RecipientType.CC, new InternetAddress(cc[0], false));
  } else if ( cc != null && cc.length > 1 ) {
    message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(StringUtils.join(cc, ",")));
  }

  // send email even if no BCC
  String[] bcc = emailMessage.getBcc();
  if ( bcc != null && bcc.length == 1 ) {
    message.setRecipient(Message.RecipientType.BCC, new InternetAddress(bcc[0], false));
  } else if ( bcc != null && bcc.length > 1 ) {
    message.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(StringUtils.join(bcc, ",")));
  }

  // set date
  message.setSentDate(new Date());
  return message;
} catch (Throwable t) {
  t.printStackTrace();
  return null;
}`
    },
    {
      name: 'sendEmail',
      args: [
        {
          name: 'emailMessage',
          javaType: 'final foam.nanos.notification.email.EmailMessage'
        }
      ],
      javaCode:
`((FixedThreadPool) getThreadPool()).submit(getX(), new ContextAgent() {
  @Override
  public void execute(X x) {
    try {
      MimeMessage message = createMimeMessage(emailMessage);
      if ( message == null ) {
        return;
      }

      // send message
      Transport transport = session_.getTransport("smtp");
      transport.connect();
      transport.sendMessage(message, message.getAllRecipients());
      transport.close();
    } catch (Throwable t) {
      t.printStackTrace();
    }
  }
});`
    },
    {
      name: 'sendEmailFromTemplate',
      javaCode:
`String group = user != null ? (String) user.getGroup() : null;
EmailTemplate emailTemplate = DAOResourceLoader.findTemplate(getX(), name, group);
if ( emailMessage == null )
  return;

for ( String key : templateArgs.keySet() ) {
  Object value = templateArgs.get(key);
  if ( value instanceof String ) {
    String s = (String) value;
    templateArgs.put(key, new String(s.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
  }
}

EnvironmentConfiguration config = getConfig(group);
JtwigTemplate template = JtwigTemplate.inlineTemplate(emailTemplate.getBody(), config);
JtwigModel model = JtwigModel.newModel(templateArgs);
emailMessage.setSubject(emailTemplate.getSubject());
emailMessage.setBody(template.render(model));
sendEmail(emailMessage);`
    },
    {
      name: 'start',
      javaReturns: 'void',
      javaCode:
`Properties props = new Properties();
props.setProperty("mail.smtp.auth", getAuthenticate() ? "true" : "false");
props.setProperty("mail.smtp.starttls.enable", getStarttls() ? "true" : "false");
props.setProperty("mail.smtp.host", getHost());
props.setProperty("mail.smtp.port", getPort());
if ( getAuthenticate() ) {
  session_ = Session.getInstance(props, new SMTPAuthenticator(getUsername(), getPassword()));
} else {
  session_ = Session.getInstance(props);
}`
    }
  ]
});
<commit_msg>Add 'enabled' property to SMTPEmailService.<commit_after>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.notification.email',
  name: 'SMTPEmailService',

  documentation: 'Implementation of Email Service using SMTP',

  implements: [
    'foam.nanos.NanoService',
    'foam.nanos.notification.email.EmailService'
  ],

  imports: [
    'threadPool?', // Only imported in Java
    'appConfig?'
  ],

  javaImports: [
    'foam.core.ContextAgent',
    'foam.core.X',
    'foam.nanos.pool.FixedThreadPool',
    'foam.util.SafetyUtil',
    'java.nio.charset.StandardCharsets',
    'java.util.Date',
    'java.util.Properties',
    'javax.mail.*',
    'javax.mail.internet.InternetAddress',
    'javax.mail.internet.MimeMessage',
    'org.apache.commons.lang3.StringUtils',
    'org.jtwig.environment.EnvironmentConfiguration',
    'org.jtwig.environment.EnvironmentConfigurationBuilder',
    'org.jtwig.JtwigModel',
    'org.jtwig.JtwigTemplate',
    'org.jtwig.resource.loader.TypedResourceLoader'
  ],

  axioms: [
    {
      name: 'javaExtras',
      buildJavaClass: function (cls) {
        cls.extras.push(foam.java.Code.create({
          data:
`private class SMTPAuthenticator extends javax.mail.Authenticator {
  protected String username_;
  protected String password_;

  public SMTPAuthenticator(String username, String password) {
    this.username_ = username;
    this.password_ = password;
  }

  @Override
  protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication(this.username_, this.password_);
  }
}

protected Session session_ = null;
protected EnvironmentConfiguration config_ = null;`
        }))
      }
    }
  ],

  properties: [
    {
      class: 'Boolean',
      name: 'enabled',
      value: true,
      javaFactory: 'return true;'
    },
    {
      class: 'String',
      name: 'host',
      value: '127.0.0.1'
    },
    {
      class: 'String',
      name: 'port',
      value: '25'
    },
    {
      class: 'Boolean',
      name: 'authenticate',
      value: false
    },
    {
      class: 'Boolean',
      name: 'starttls',
      value: false
    },
    {
      class: 'String',
      name: 'username',
      value: null
    },
    {
      class: 'String',
      name: 'password',
      value: null
    },
    {
      class: 'String',
      name: 'from',
      value: null
    },
    {
      class: 'String',
      name: 'displayName',
      value: null
    },
    {
      class: 'String',
      name: 'replyTo',
      value: null
    }
  ],

  methods: [
    {
      name: 'getConfig',
      javaReturns: 'EnvironmentConfiguration',
      args: [
        {
          name: 'group',
          javaType: 'String'
        }
      ],
      javaCode:
`if ( config_ == null ) {
  config_ = EnvironmentConfigurationBuilder
    .configuration()
    .resources()
      .resourceLoaders()
        .add(new TypedResourceLoader("dao", new DAOResourceLoader(getX(), group)))
      .and()
    .and()
  .build();
}
return config_;`
    },
    {
      name: 'createMimeMessage',
      javaReturns: 'MimeMessage',
      args: [
        {
          name: 'emailMessage',
          javaType: 'foam.nanos.notification.email.EmailMessage'
        }
      ],
      javaCode:
`try {
  MimeMessage message = new MimeMessage(session_);

  // don't send email if no sender
  String from = getFrom();
  if ( SafetyUtil.isEmpty(from) )
    return null;

  // add display name if present
  String displayName = getDisplayName();
  if ( SafetyUtil.isEmpty(displayName) ) {
    message.setFrom(new InternetAddress(from));
  } else {
    message.setFrom(new InternetAddress(from, displayName));
  }

  // attach reply to if present
  String replyTo = getReplyTo();
  if ( ! SafetyUtil.isEmpty(replyTo) ) {
    message.setReplyTo(InternetAddress.parse(replyTo));
  }

  // don't send email if no subject
  String subject = emailMessage.getSubject();
  if ( SafetyUtil.isEmpty(subject) )
    return null;
  message.setSubject(subject);

  // don't send email if no body
  String body = emailMessage.getBody();
  if ( SafetyUtil.isEmpty(body) )
    return null;
  message.setContent(body, "text/html; charset=utf-8");

  // don't send email if no recipient
  String[] to = emailMessage.getTo();
  if ( to == null || to.length <= 0 )
    return null;

  if ( to.length == 1 ) {
    message.setRecipient(Message.RecipientType.TO, new InternetAddress(to[0], false));
  } else {
    message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(StringUtils.join(to, ",")));
  }

  // send email even if no CC
  String[] cc = emailMessage.getCc();
  if ( cc != null && cc.length == 1 ) {
    message.setRecipient(Message.RecipientType.CC, new InternetAddress(cc[0], false));
  } else if ( cc != null && cc.length > 1 ) {
    message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(StringUtils.join(cc, ",")));
  }

  // send email even if no BCC
  String[] bcc = emailMessage.getBcc();
  if ( bcc != null && bcc.length == 1 ) {
    message.setRecipient(Message.RecipientType.BCC, new InternetAddress(bcc[0], false));
  } else if ( bcc != null && bcc.length > 1 ) {
    message.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(StringUtils.join(bcc, ",")));
  }

  // set date
  message.setSentDate(new Date());
  return message;
} catch (Throwable t) {
  t.printStackTrace();
  return null;
}`
    },
    {
      name: 'sendEmail',
      args: [
        {
          name: 'emailMessage',
          javaType: 'final foam.nanos.notification.email.EmailMessage'
        }
      ],
      javaCode: `
if ( ! this.getEnabled() ) return;

((FixedThreadPool) getThreadPool()).submit(getX(), new ContextAgent() {
  @Override
  public void execute(X x) {
    try {
      MimeMessage message = createMimeMessage(emailMessage);
      if ( message == null ) {
        return;
      }

      // send message
      Transport transport = session_.getTransport("smtp");
      transport.connect();
      transport.sendMessage(message, message.getAllRecipients());
      transport.close();
    } catch (Throwable t) {
      t.printStackTrace();
    }
  }
});`
    },
    {
      name: 'sendEmailFromTemplate',
      javaCode: `
if ( ! this.getEnabled() ) return;

String group = user != null ? (String) user.getGroup() : null;
EmailTemplate emailTemplate = DAOResourceLoader.findTemplate(getX(), name, group);
if ( emailMessage == null )
  return;

for ( String key : templateArgs.keySet() ) {
  Object value = templateArgs.get(key);
  if ( value instanceof String ) {
    String s = (String) value;
    templateArgs.put(key, new String(s.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
  }
}

EnvironmentConfiguration config = getConfig(group);
JtwigTemplate template = JtwigTemplate.inlineTemplate(emailTemplate.getBody(), config);
JtwigModel model = JtwigModel.newModel(templateArgs);
emailMessage.setSubject(emailTemplate.getSubject());
emailMessage.setBody(template.render(model));
sendEmail(emailMessage);`
    },
    {
      name: 'start',
      javaReturns: 'void',
      javaCode:
`Properties props = new Properties();
props.setProperty("mail.smtp.auth", getAuthenticate() ? "true" : "false");
props.setProperty("mail.smtp.starttls.enable", getStarttls() ? "true" : "false");
props.setProperty("mail.smtp.host", getHost());
props.setProperty("mail.smtp.port", getPort());
if ( getAuthenticate() ) {
  session_ = Session.getInstance(props, new SMTPAuthenticator(getUsername(), getPassword()));
} else {
  session_ = Session.getInstance(props);
}`
    }
  ]
});
<|endoftext|>


<commit_before>module.exports = function(siOptions) {
  var siUtil = {}

  siUtil.tellMeAboutMySearchIndex = function (callback) {
    siOptions.indexes.get('DOCUMENT-COUNT', function (err, docCount) {
      siOptions.indexes.get('LAST-UPDATE-TIMESTAMP', function (err, lastUpdate) {
        var obj = {}
        obj.totalDocs = docCount || 0
        obj.lastUpdate = lastUpdate || 0

        obj.indexPath = siOptions.indexPath
        obj.deletable = siOptions.deletable
        obj.fieldedSearch = siOptions.fieldedSearch
        obj.store = siOptions.store
        obj.logLevel = siOptions.logLevel
        obj.nGramLength = siOptions.nGramLength
        obj.nGramSeparator = siOptions.nGramSeparator
        obj.separator = siOptions.separator
        obj.stopwords = siOptions.stopwords

        callback(null, obj)
      })
    })
  }

  siUtil.close = function (callback) {
    siOptions.indexes.close(function (err) {
      while (!siOptions.indexes.isClosed()) {
        //log not always working here- investigate
       siOptions.log.info('closing...')
      }
      if (siOptions.indexes.isClosed()) {
       siOptions.log.info('closed...')
        callback(err)
      }
    })
  }

  return siUtil
}
<commit_msg>fixed faulty logger<commit_after>module.exports = function(siOptions) {
  var siUtil = {}

  siUtil.tellMeAboutMySearchIndex = function (callback) {
    siOptions.indexes.get('DOCUMENT-COUNT', function (err, docCount) {
      siOptions.indexes.get('LAST-UPDATE-TIMESTAMP', function (err, lastUpdate) {
        var obj = {}
        obj.totalDocs = docCount || 0
        obj.lastUpdate = lastUpdate || 0

        obj.indexPath = siOptions.indexPath
        obj.deletable = siOptions.deletable
        obj.fieldedSearch = siOptions.fieldedSearch
        obj.store = siOptions.store
        obj.logLevel = siOptions.logLevel
        obj.nGramLength = siOptions.nGramLength
        obj.nGramSeparator = siOptions.nGramSeparator
        obj.separator = siOptions.separator
        obj.stopwords = siOptions.stopwords

        callback(null, obj)
      })
    })
  }

  siUtil.close = function (callback) {
    siOptions.indexes.close(function (err) {
      while (!siOptions.indexes.isClosed()) {
        //log not always working here- investigate
        if (siOptions.log) siOptions.log.info('closing...')
      }
      if (siOptions.indexes.isClosed()) {
        if (siOptions.log) siOptions.log.info('closed...')
        callback(err)
      }
    })
  }

  return siUtil
}
<|endoftext|>


<commit_before>(function() {
  var Compiler, HAML_EXTENSION_REGEXP, Parser, Q, Riline, Slimmy, fs, walk, _;

  Q = require('q');

  _ = require('underscore');

  fs = require('fs');

  walk = require('walk');

  Riline = require('riline');

  Parser = require('./parser');

  Compiler = require('./compiler');

  HAML_EXTENSION_REGEXP = /\.haml$/;

  Slimmy = (function() {
    function _Class() {}

    _Class.prototype.Parser = Parser;

    _Class.prototype.Compiler = Compiler;

    _Class.prototype.convertString = function(hamlCodeString, fileCompilationMode) {
      if (fileCompilationMode == null) {
        fileCompilationMode = false;
      }
      return this.parser().parseString(hamlCodeString).then((function(_this) {
        return function(rootNode) {
          var compiler;
          compiler = new _this.Compiler(rootNode, fileCompilationMode);
          compiler.compile();
          _this._showWarnings(compiler);
          return compiler;
        };
      })(this));
    };

    _Class.prototype.convertFile = function(filePath, writeToFile) {
      if (writeToFile == null) {
        writeToFile = false;
      }
      filePath = this.getAbsolutePath(filePath);
      return this.parser().parseFile(filePath).then((function(_this) {
        return function(rootNode) {
          var compiler;
          compiler = new _this.Compiler(rootNode);
          compiler.compile();
          if (writeToFile) {
            _this._showWarnings(compiler, filePath);
          } else {
            _this._showWarnings(compiler);
          }
          _this._compilationResults = compiler.buffer;
          if (writeToFile) {
            return _this.writeToSlimFile(filePath, compiler.buffer);
          }
        };
      })(this));
    };

    _Class.prototype.convertDir = function(dirPath, writeToFile) {
      var files, walker;
      if (writeToFile == null) {
        writeToFile = false;
      }
      dirPath = this.getAbsolutePath(dirPath);
      files = [];
      walker = walk.walkSync(dirPath, {
        followLinks: false,
        listeners: {
          file: function(root, stat, next) {
            if (HAML_EXTENSION_REGEXP.test(stat.name)) {
              files.push("" + root + "/" + stat.name);
            }
            return next();
          }
        }
      });
      console.log("Converting files:");
      return Q.allSettled(_.map(files, (function(_this) {
        return function(file) {
          console.log(file);
          return _this.convertFile(file, writeToFile);
        };
      })(this)))["catch"](function(e) {
        return console.log(e);
      }).then(function() {
        return console.log('All files are converted.');
      });
    };

    _Class.prototype.writeToSlimFile = function(filePath, slimCode) {
      var fd, slimFilePath;
      slimFilePath = this.getSlimPath(filePath);
      fd = fs.openSync(slimFilePath, 'w');
      fs.writeFileSync(slimFilePath, slimCode);
      return fs.closeSync(fd);
    };

    _Class.prototype.getAbsolutePath = function(path) {
      var isAbsolutePath;
      isAbsolutePath = path[0] === '/' || path[0] === '~';
      if (isAbsolutePath) {
        return path;
      } else {
        return path = "" + __dirname + "/../" + path;
      }
    };

    _Class.prototype.getSlimPath = function(path) {
      return path.replace(HAML_EXTENSION_REGEXP, '.slim');
    };

    _Class.prototype.parser = function() {
      return this._parser != null ? this._parser : this._parser = new this.Parser();
    };

    _Class.prototype._showWarnings = function(compiler, filePath) {
      var riline, text, warning, _i, _len, _ref;
      if (compiler.warnings == null) {
        return;
      }
      riline = new Riline(compiler.buffer);
      _ref = compiler.warnings;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        warning = _ref[_i];
        text = warning.text;
        if (filePath) {
          text += '\n' + this.getSlimPath(filePath);
        }
        riline.addMessage({
          text: text,
          startLine: warning.startLine,
          endLine: warning.endLine
        });
      }
      return riline.printMessages();
    };

    return _Class;

  })();

  module.exports = Slimmy;

}).call(this);
<commit_msg>Release<commit_after>(function() {
  var Compiler, HAML_EXTENSION_REGEXP, Parser, Q, Riline, Slimmy, fs, walk, _;

  Q = require('q');

  _ = require('underscore');

  fs = require('fs');

  walk = require('walk');

  Riline = require('riline');

  Parser = require('./parser');

  Compiler = require('./compiler');

  HAML_EXTENSION_REGEXP = /\.haml$/;

  Slimmy = (function() {
    function _Class() {}

    _Class.prototype.Parser = Parser;

    _Class.prototype.Compiler = Compiler;

    _Class.prototype.convertString = function(hamlCodeString, fileCompilationMode) {
      if (fileCompilationMode == null) {
        fileCompilationMode = false;
      }
      return this.parser().parseString(hamlCodeString).then((function(_this) {
        return function(rootNode) {
          var compiler;
          compiler = new _this.Compiler(rootNode, fileCompilationMode);
          compiler.compile();
          _this._showWarnings(compiler);
          return compiler;
        };
      })(this));
    };

    _Class.prototype.convertFile = function(filePath, writeToFile) {
      if (writeToFile == null) {
        writeToFile = true;
      }
      filePath = this.getAbsolutePath(filePath);
      return this.parser().parseFile(filePath).then((function(_this) {
        return function(rootNode) {
          var compiler;
          compiler = new _this.Compiler(rootNode);
          compiler.compile();
          if (writeToFile) {
            _this._showWarnings(compiler, filePath);
          } else {
            _this._showWarnings(compiler);
          }
          _this._compilationResults = compiler.buffer;
          if (writeToFile) {
            return _this.writeToSlimFile(filePath, compiler.buffer);
          }
        };
      })(this));
    };

    _Class.prototype.convertDir = function(dirPath, writeToFile) {
      var files, walker;
      if (writeToFile == null) {
        writeToFile = true;
      }
      dirPath = this.getAbsolutePath(dirPath);
      files = [];
      walker = walk.walkSync(dirPath, {
        followLinks: false,
        listeners: {
          file: function(root, stat, next) {
            if (HAML_EXTENSION_REGEXP.test(stat.name)) {
              files.push("" + root + "/" + stat.name);
            }
            return next();
          }
        }
      });
      console.log("Converting files:");
      return Q.allSettled(_.map(files, (function(_this) {
        return function(file) {
          console.log(file);
          return _this.convertFile(file, writeToFile);
        };
      })(this)))["catch"](function(e) {
        return console.log(e);
      }).then(function() {
        return console.log('All files are converted.');
      });
    };

    _Class.prototype.writeToSlimFile = function(filePath, slimCode) {
      var fd, slimFilePath;
      slimFilePath = this.getSlimPath(filePath);
      fd = fs.openSync(slimFilePath, 'w');
      fs.writeFileSync(slimFilePath, slimCode);
      return fs.closeSync(fd);
    };

    _Class.prototype.getAbsolutePath = function(path) {
      var isAbsolutePath;
      isAbsolutePath = path[0] === '/' || path[0] === '~';
      if (isAbsolutePath) {
        return path;
      } else {
        return path = "" + __dirname + "/../" + path;
      }
    };

    _Class.prototype.getSlimPath = function(path) {
      return path.replace(HAML_EXTENSION_REGEXP, '.slim');
    };

    _Class.prototype.parser = function() {
      return this._parser != null ? this._parser : this._parser = new this.Parser();
    };

    _Class.prototype._showWarnings = function(compiler, filePath) {
      var riline, text, warning, _i, _len, _ref;
      if (compiler.warnings == null) {
        return;
      }
      riline = new Riline(compiler.buffer);
      _ref = compiler.warnings;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        warning = _ref[_i];
        text = warning.text;
        if (filePath) {
          text += '\n' + this.getSlimPath(filePath);
        }
        riline.addMessage({
          text: text,
          startLine: warning.startLine,
          endLine: warning.endLine
        });
      }
      return riline.printMessages();
    };

    return _Class;

  })();

  module.exports = Slimmy;

}).call(this);
<|endoftext|>