<commit_before>var color          = require('color');
var debug          = require("debug")('Prismatik');
var prismatik      = require("./lib/prismatik-client");

module.exports = function (homebridge)
{
  if(typeof homebridge !== "undefined")
  {
    Service         = homebridge.hap.Service;
    Characteristic  = homebridge.hap.Characteristic;
    Accessory       = homebridge.hap.Accessory;

    console.log("Prismatik initializing");
  }

  homebridge.registerAccessory("homebridge-prismatik", "Prismatik", PrismatikAccessory);
}

function PrismatikAccessory(log, config) {
  this.log    = log;

  this.host   = config['host'];
  this.port   = config['port'];
  this.apikey = config["apikey"];

  this.hue = 0;
  this.sat = 100;
  this.bri = 50;
}

PrismatikAccessory.prototype = {

  getPowerState: function(callback) {

    var options = {
       host: this.host,
       port: this.port,
       apikey: this.apikey
    };

    prismatik.connect(function(isConnected) {
      if (isConnected) {
        prismatik.getStatus(function(power) {
          this.log("Getting power status: %s", power);
          callback(null, power);

          prismatik.disconnect();
        }.bind(this));
      } else {
        this.log("Failed to connect to Prismatik");
        callback(null, false);
      }
    }.bind(this), options);

  },

  setPowerState: function(powerOn, callback) {

    var options = {
       host: this.host,
       port: this.port,
       apikey: this.apikey
    };

    prismatik.connect(function(isConnected) {
       if (isConnected) {
          prismatik.lock(function(success) {
             if (success) {
                if (powerOn) {
                  prismatik.turnOn(function() {
                    this.log("Turning on!");
                    callback();
                  }.bind(this));
                } else {
                  prismatik.turnOff(function() {
                    this.log("Turning off!");
                    callback();
                  }.bind(this));
                }
             } else {
                this.log("Could not lock, something else has already connected.");
                prismatik.disconnect();
                callback();
             }
          }.bind(this));
       } else {
          this.log("Failed to connect to Prismatik");
          callback();
       }
    }.bind(this), options);

  },

  setBrightness: function(level, callback) {

    this.log("Setting brightness to %s", level);

    var options = {
       host: this.host,
       port: this.port,
       apikey: this.apikey
    };

    prismatik.connect(function(isConnected) {
       if (isConnected) {
          prismatik.lock(function(success) {
             if (success) {
                prismatik.setBrightness(level, function() {
                  callback();
                }.bind(this));
             } else {
                this.log("Could not lock, something else has already connected.");
                prismatik.disconnect();
                callback();
             }
          }.bind(this));
       } else {
          this.log("Failed to connect to Prismatik");
          callback();
       }
    }.bind(this), options);

  },

  setHue: function(hue, callback) {

    this.log("Setting hue to %s", hue);
    this.hue = hue;

    var hsl = color({h: Math.round(this.hue), s: Math.round(this.sat), l: Math.round(this.bri)});

    var options = {
       host: this.host,
       port: this.port,
       apikey: this.apikey
    };

    prismatik.connect(function(isConnected) {
       if (isConnected) {
          prismatik.lock(function(success) {
             if (success) {
                prismatik.setColorToAll(hsl.red(), hsl.green(), hsl.blue(), function() {
                  callback();
                }.bind(this));
             } else {
                this.log("Could not lock, something else has already connected.");
                prismatik.disconnect();
                callback();
             }
          }.bind(this));
       } else {
          this.log("Failed to connect to Prismatik");
          callback();
       }
    }.bind(this), options);

  },

  setSaturation: function(saturation, callback) {

    this.log("Setting saturation to %s", saturation);
    this.sat = saturation;

    var hsl = color({h: Math.round(this.hue), s: Math.round(this.sat), l: Math.round(this.bri)});

    var options = {
       host: this.host,
       port: this.port,
       apikey: this.apikey
    };

    prismatik.connect(function(isConnected) {
       if (isConnected) {
          prismatik.lock(function(success) {
             if (success) {
                prismatik.setColorToAll(hsl.red(), hsl.green(), hsl.blue(), function() {
                  callback();
                }.bind(this));
             } else {
                this.log("Could not lock, something else has already connected.");
                prismatik.disconnect();
                callback();
             }
          }.bind(this));
       } else {
          this.log("Failed to connect to Prismatik");
          callback();
       }
    }.bind(this), options);

  },

  identify: function(callback) {
    this.log("Identify requested!");
    callback(); // success
  },

  getServices: function() {

    // you can OPTIONALLY create an information service if you wish to override
    // the default values for things like serial number, model, etc.
    var informationService = new Service.AccessoryInformation();

    informationService
      .setCharacteristic(Characteristic.Manufacturer, "Prismatik Manufacturer")
      .setCharacteristic(Characteristic.Model, "Prismatik Model")
      .setCharacteristic(Characteristic.SerialNumber, "Prismatik Serial Number");

    var lightbulbService = new Service.Lightbulb();

    lightbulbService
      .getCharacteristic(Characteristic.On)
      .on('set', this.setPowerState.bind(this))
      .on('get', this.getPowerState.bind(this));

    lightbulbService
      .addCharacteristic(new Characteristic.Brightness())
      .on('set', this.setBrightness.bind(this));

    lightbulbService
      .addCharacteristic(new Characteristic.Hue())
      .on('set', this.setHue.bind(this));

    lightbulbService
      .addCharacteristic(new Characteristic.Saturation())
      .on('set', this.setSaturation.bind(this));

    return [informationService, lightbulbService];
  }
};
<commit_msg>Removed unused 'debug' module.<commit_after>var color          = require('color');
var prismatik      = require("./lib/prismatik-client");

module.exports = function (homebridge)
{
  if(typeof homebridge !== "undefined")
  {
    Service         = homebridge.hap.Service;
    Characteristic  = homebridge.hap.Characteristic;
    Accessory       = homebridge.hap.Accessory;

    console.log("Prismatik initializing");
  }

  homebridge.registerAccessory("homebridge-prismatik", "Prismatik", PrismatikAccessory);
}

function PrismatikAccessory(log, config) {
  this.log    = log;

  this.host   = config['host'];
  this.port   = config['port'];
  this.apikey = config["apikey"];

  this.hue = 0;
  this.sat = 100;
  this.bri = 50;
}

PrismatikAccessory.prototype = {

  getPowerState: function(callback) {

    var options = {
       host: this.host,
       port: this.port,
       apikey: this.apikey
    };

    prismatik.connect(function(isConnected) {
      if (isConnected) {
        prismatik.getStatus(function(power) {
          this.log("Getting power status: %s", power);
          callback(null, power);

          prismatik.disconnect();
        }.bind(this));
      } else {
        this.log("Failed to connect to Prismatik");
        callback(null, false);
      }
    }.bind(this), options);

  },

  setPowerState: function(powerOn, callback) {

    var options = {
       host: this.host,
       port: this.port,
       apikey: this.apikey
    };

    prismatik.connect(function(isConnected) {
       if (isConnected) {
          prismatik.lock(function(success) {
             if (success) {
                if (powerOn) {
                  prismatik.turnOn(function() {
                    this.log("Turning on!");
                    callback();
                  }.bind(this));
                } else {
                  prismatik.turnOff(function() {
                    this.log("Turning off!");
                    callback();
                  }.bind(this));
                }
             } else {
                this.log("Could not lock, something else has already connected.");
                prismatik.disconnect();
                callback();
             }
          }.bind(this));
       } else {
          this.log("Failed to connect to Prismatik");
          callback();
       }
    }.bind(this), options);

  },

  setBrightness: function(level, callback) {

    this.log("Setting brightness to %s", level);

    var options = {
       host: this.host,
       port: this.port,
       apikey: this.apikey
    };

    prismatik.connect(function(isConnected) {
       if (isConnected) {
          prismatik.lock(function(success) {
             if (success) {
                prismatik.setBrightness(level, function() {
                  callback();
                }.bind(this));
             } else {
                this.log("Could not lock, something else has already connected.");
                prismatik.disconnect();
                callback();
             }
          }.bind(this));
       } else {
          this.log("Failed to connect to Prismatik");
          callback();
       }
    }.bind(this), options);

  },

  setHue: function(hue, callback) {

    this.log("Setting hue to %s", hue);
    this.hue = hue;

    var hsl = color({h: Math.round(this.hue), s: Math.round(this.sat), l: Math.round(this.bri)});

    var options = {
       host: this.host,
       port: this.port,
       apikey: this.apikey
    };

    prismatik.connect(function(isConnected) {
       if (isConnected) {
          prismatik.lock(function(success) {
             if (success) {
                prismatik.setColorToAll(hsl.red(), hsl.green(), hsl.blue(), function() {
                  callback();
                }.bind(this));
             } else {
                this.log("Could not lock, something else has already connected.");
                prismatik.disconnect();
                callback();
             }
          }.bind(this));
       } else {
          this.log("Failed to connect to Prismatik");
          callback();
       }
    }.bind(this), options);

  },

  setSaturation: function(saturation, callback) {

    this.log("Setting saturation to %s", saturation);
    this.sat = saturation;

    var hsl = color({h: Math.round(this.hue), s: Math.round(this.sat), l: Math.round(this.bri)});

    var options = {
       host: this.host,
       port: this.port,
       apikey: this.apikey
    };

    prismatik.connect(function(isConnected) {
       if (isConnected) {
          prismatik.lock(function(success) {
             if (success) {
                prismatik.setColorToAll(hsl.red(), hsl.green(), hsl.blue(), function() {
                  callback();
                }.bind(this));
             } else {
                this.log("Could not lock, something else has already connected.");
                prismatik.disconnect();
                callback();
             }
          }.bind(this));
       } else {
          this.log("Failed to connect to Prismatik");
          callback();
       }
    }.bind(this), options);

  },

  identify: function(callback) {
    this.log("Identify requested!");
    callback(); // success
  },

  getServices: function() {

    // you can OPTIONALLY create an information service if you wish to override
    // the default values for things like serial number, model, etc.
    var informationService = new Service.AccessoryInformation();

    informationService
      .setCharacteristic(Characteristic.Manufacturer, "Prismatik Manufacturer")
      .setCharacteristic(Characteristic.Model, "Prismatik Model")
      .setCharacteristic(Characteristic.SerialNumber, "Prismatik Serial Number");

    var lightbulbService = new Service.Lightbulb();

    lightbulbService
      .getCharacteristic(Characteristic.On)
      .on('set', this.setPowerState.bind(this))
      .on('get', this.getPowerState.bind(this));

    lightbulbService
      .addCharacteristic(new Characteristic.Brightness())
      .on('set', this.setBrightness.bind(this));

    lightbulbService
      .addCharacteristic(new Characteristic.Hue())
      .on('set', this.setHue.bind(this));

    lightbulbService
      .addCharacteristic(new Characteristic.Saturation())
      .on('set', this.setSaturation.bind(this));

    return [informationService, lightbulbService];
  }
};
<|endoftext|>


<commit_before>'use strict';

var gutil = require('gulp-util');
var File = require('vinyl');
var MemoryFileSystem = require('memory-fs');
var through = require('through');
var ProgressPlugin = require('webpack/lib/ProgressPlugin');
var clone = require('lodash.clone');

var defaultStatsOptions = {
  colors: gutil.colors.supportsColor,
  hash: false,
  timings: false,
  chunks: false,
  chunkModules: false,
  modules: false,
  children: true,
  version: true,
  cached: false,
  cachedAssets: false,
  reasons: false,
  source: false,
  errorDetails: false
};

module.exports = function (options, wp, done) {
  options = clone(options) || {};
  if (typeof done !== 'function') {
    var callingDone = false;
    done = function (err, stats) {
      if (err) {
        // The err is here just to match the API but isnt used
        return;
      }
      stats = stats || {};
      if (options.quiet || callingDone) {
        return;
      }
      // Debounce output a little for when in watch mode
      if (options.watch) {
        callingDone = true;
        setTimeout(function () {
          callingDone = false;
        }, 500);
      }
      if (options.verbose) {
        gutil.log(stats.toString({
          colors: gutil.colors.supportsColor
        }));
      } else {
        var statsOptions = options && options.stats || {};

        Object.keys(defaultStatsOptions).forEach(function (key) {
          if (typeof statsOptions[key] === 'undefined') {
            statsOptions[key] = defaultStatsOptions[key];
          }
        });

        gutil.log(stats.toString(statsOptions));
      }
    };
  }

  var webpack = wp || require('webpack');
  var entry = [];
  var entries = Object.create(null);

  var stream = through(function (file) {
    if (file.isNull()) {
      return;
    }
    if ('named' in file) {
      if (!Array.isArray(entries[file.named])) {
        entries[file.named] = [];
      }
      entries[file.named].push(file.path);
    } else {
      entry = entry || [];
      entry.push(file.path);
    }
  }, function () {
    var self = this;
    options.output = options.output || {};

    // Determine pipe'd in entry
    if (Object.keys(entries).length > 0) {
      entry = entries;
      if (!options.output.filename) {
        // Better output default for multiple chunks
        options.output.filename = '[name].js';
      }
    } else if (entry.length < 2) {
      entry = entry[0] || entry;
    }

    options.entry = options.entry || entry;
    options.output.path = options.output.path || process.cwd();
    options.output.filename = options.output.filename || '[hash].js';
    entry = [];

    if (!options.entry || options.entry.length < 1) {
      gutil.log('webpack-stream - No files given; aborting compilation');
      return self.emit('end');
    }

    var compiler = webpack(options, function (err, stats) {
      if (err) {
        self.emit('error', new gutil.PluginError('webpack-stream', err));
      }
      var jsonStats = stats.toJson() || {};
      var errors = jsonStats.errors || [];
      if (errors.length) {
        var errorMessage = errors.reduce(function (resultMessage, nextError) {
          return resultMessage += nextError.toString();
         }, "");
        self.emit('error', new gutil.PluginError('webpack-stream', errorMessage));
      }
      if (!options.watch) {
        self.queue(null);
      }
      done(err, stats);
      if (options.watch && !options.quiet) {
        gutil.log('webpack is watching for changes');
      }
    });

    // In watch mode webpack returns a wrapper object so we need to get
    // the underlying compiler
    if (options.watch) {
      compiler = compiler.compiler;
    }

    if (options.progress) {
      compiler.apply(new ProgressPlugin(function (percentage, msg) {
        percentage = Math.floor(percentage * 100);
        msg = percentage + '% ' + msg;
        if (percentage < 10) msg = ' ' + msg;
        gutil.log('webpack', msg);
      }));
    }

    var fs = compiler.outputFileSystem = new MemoryFileSystem();

    compiler.plugin('after-emit', function (compilation, callback) {
      Object.keys(compilation.assets).forEach(function (outname) {
        if (compilation.assets[outname].emitted) {
          var file = prepareFile(fs, compiler, outname);
          self.queue(file);
        }
      });
      callback();
    });
  });

  // If entry point manually specified, trigger that
  if (options.entry) {
    stream.end();
  }

  return stream;
};

function prepareFile (fs, compiler, outname) {
  var path = fs.join(compiler.outputPath, outname);
  if (path.indexOf('?') !== -1) {
    path = path.split('?')[0];
  }
  var contents = fs.readFileSync(path);
  var file = new File({
    base: compiler.outputPath,
    path: path,
    contents: contents
  });
  return file;
}

// Expose webpack if asked
Object.defineProperty(module.exports, 'webpack', {
  get: function () {
    return require('webpack');
  }
});
<commit_msg>Fixing standard errors<commit_after>'use strict';

var gutil = require('gulp-util');
var File = require('vinyl');
var MemoryFileSystem = require('memory-fs');
var through = require('through');
var ProgressPlugin = require('webpack/lib/ProgressPlugin');
var clone = require('lodash.clone');

var defaultStatsOptions = {
  colors: gutil.colors.supportsColor,
  hash: false,
  timings: false,
  chunks: false,
  chunkModules: false,
  modules: false,
  children: true,
  version: true,
  cached: false,
  cachedAssets: false,
  reasons: false,
  source: false,
  errorDetails: false
};

module.exports = function (options, wp, done) {
  options = clone(options) || {};
  if (typeof done !== 'function') {
    var callingDone = false;
    done = function (err, stats) {
      if (err) {
        // The err is here just to match the API but isnt used
        return;
      }
      stats = stats || {};
      if (options.quiet || callingDone) {
        return;
      }
      // Debounce output a little for when in watch mode
      if (options.watch) {
        callingDone = true;
        setTimeout(function () {
          callingDone = false;
        }, 500);
      }
      if (options.verbose) {
        gutil.log(stats.toString({
          colors: gutil.colors.supportsColor
        }));
      } else {
        var statsOptions = options && options.stats || {};

        Object.keys(defaultStatsOptions).forEach(function (key) {
          if (typeof statsOptions[key] === 'undefined') {
            statsOptions[key] = defaultStatsOptions[key];
          }
        });

        gutil.log(stats.toString(statsOptions));
      }
    };
  }

  var webpack = wp || require('webpack');
  var entry = [];
  var entries = Object.create(null);

  var stream = through(function (file) {
    if (file.isNull()) {
      return;
    }
    if ('named' in file) {
      if (!Array.isArray(entries[file.named])) {
        entries[file.named] = [];
      }
      entries[file.named].push(file.path);
    } else {
      entry = entry || [];
      entry.push(file.path);
    }
  }, function () {
    var self = this;
    options.output = options.output || {};

    // Determine pipe'd in entry
    if (Object.keys(entries).length > 0) {
      entry = entries;
      if (!options.output.filename) {
        // Better output default for multiple chunks
        options.output.filename = '[name].js';
      }
    } else if (entry.length < 2) {
      entry = entry[0] || entry;
    }

    options.entry = options.entry || entry;
    options.output.path = options.output.path || process.cwd();
    options.output.filename = options.output.filename || '[hash].js';
    entry = [];

    if (!options.entry || options.entry.length < 1) {
      gutil.log('webpack-stream - No files given; aborting compilation');
      return self.emit('end');
    }

    var compiler = webpack(options, function (err, stats) {
      if (err) {
        self.emit('error', new gutil.PluginError('webpack-stream', err));
      }
      var jsonStats = stats.toJson() || {};
      var errors = jsonStats.errors || [];
      if (errors.length) {
        var errorMessage = errors.reduce(function (resultMessage, nextError) {
          resultMessage += nextError.toString();
          return resultMessage;
        }, '');
        self.emit('error', new gutil.PluginError('webpack-stream', errorMessage));
      }
      if (!options.watch) {
        self.queue(null);
      }
      done(err, stats);
      if (options.watch && !options.quiet) {
        gutil.log('webpack is watching for changes');
      }
    });

    // In watch mode webpack returns a wrapper object so we need to get
    // the underlying compiler
    if (options.watch) {
      compiler = compiler.compiler;
    }

    if (options.progress) {
      compiler.apply(new ProgressPlugin(function (percentage, msg) {
        percentage = Math.floor(percentage * 100);
        msg = percentage + '% ' + msg;
        if (percentage < 10) msg = ' ' + msg;
        gutil.log('webpack', msg);
      }));
    }

    var fs = compiler.outputFileSystem = new MemoryFileSystem();

    compiler.plugin('after-emit', function (compilation, callback) {
      Object.keys(compilation.assets).forEach(function (outname) {
        if (compilation.assets[outname].emitted) {
          var file = prepareFile(fs, compiler, outname);
          self.queue(file);
        }
      });
      callback();
    });
  });

  // If entry point manually specified, trigger that
  if (options.entry) {
    stream.end();
  }

  return stream;
};

function prepareFile (fs, compiler, outname) {
  var path = fs.join(compiler.outputPath, outname);
  if (path.indexOf('?') !== -1) {
    path = path.split('?')[0];
  }
  var contents = fs.readFileSync(path);
  var file = new File({
    base: compiler.outputPath,
    path: path,
    contents: contents
  });
  return file;
}

// Expose webpack if asked
Object.defineProperty(module.exports, 'webpack', {
  get: function () {
    return require('webpack');
  }
});
<|endoftext|>


<commit_before>var ngAnnotate = require('ng-annotate'),
    SourceMapSource = require('webpack-core/lib/SourceMapSource');

function ngAnnotatePlugin(options) {
    this.options = options || { add: true };
}

ngAnnotatePlugin.prototype.apply = function apply(compiler) {
    var options = this.options;

    compiler.plugin('compilation', function(compilation) {
        compilation.plugin('optimize-chunk-assets', function(chunks, callback) {
            var files = [];

            function getFilesFromChunk(chunk) {
                files = files.concat(chunk.files);
            }

            function annotateFile(file) {
                var map = compilation.assets[file].map(),
                    value = ngAnnotate(compilation.assets[file].source(), options);

                if (!value.errors) {
                    compilation.assets[file] = new SourceMapSource(value.src, file, map);
                }
            }

            chunks.forEach(getFilesFromChunk);

            files = files.concat(compilation.additionalChunkAssets);

            files.forEach(annotateFile);

            callback();
        });
    });
};

module.exports = ngAnnotatePlugin;
<commit_msg>Add option for source maps, and pass to ng-annotate.<commit_after>
var ngAnnotate = require('ng-annotate'),
    SourceMapSource = require('webpack-core/lib/SourceMapSource');

function ngAnnotatePlugin(options) {
    this.options = options || { add: true, sourceMap: false };
}

ngAnnotatePlugin.prototype.apply = function apply(compiler) {
    var options = this.options;

    compiler.plugin('compilation', function(compilation) {
        compilation.plugin('optimize-chunk-assets', function(chunks, callback) {
            var files = [];

            function getFilesFromChunk(chunk) {
                files = files.concat(chunk.files);
            }

            function annotateFile(file) {
                if (options.sourceMap) {
                    options.map = {
                        inFile: file,
                        sourceRoot: ""
                    };
                }
                var value = ngAnnotate(compilation.assets[file].source(), options);

                var asset = compilation.assets[file];

                if (options.sourceMap && asset.sourceAndMap) {
                    var sourceAndMap = asset.sourceAndMap();
                    var map = sourceAndMap.map;
                    var input = sourceAndMap.source;
                } else {
                    map = asset.map();
                }

                if (!value.errors) {
                    if (options.sourceMap) {
                        compilation.assets[file] = new SourceMapSource(value.src, file, JSON.parse(value.map), input, map);
                    }
                    else {
                        compilation.assets[file] = new SourceMapSource(value.src, file, map);
                    }
                }
            }

            chunks.forEach(getFilesFromChunk);

            files = files.concat(compilation.additionalChunkAssets);

            files.forEach(annotateFile);

            callback();
        });
    });
};

module.exports = ngAnnotatePlugin;
<|endoftext|>


<commit_before>/**
 * Configure the persistence options
 */

var config = {};
if (process.env.MONGOLAB_URI) {
    var BotkitStorage = require('botkit-storage-mongo');
    config = {
        storage: BotkitStorage({mongoUri: process.env.MONGOLAB_URI}),
    };
} else {
    config = {
        json_file_store: ((process.env.TOKEN)?'./db_slack_bot_ci/':'./db_slack_bot_a/'), //use a different name if an app or CI
    };
}

/**
 * Are being run as an app or a custom integration? The initialization will differ, depending
 */

if (process.env.TOKEN || process.env.SLACK_TOKEN) {
    //Treat this as a custom integration
    var customIntegration = require('./lib/custom_integrations');
    var token = (process.env.TOKEN) ? process.env.TOKEN : process.env.SLACK_TOKEN;
    var controller = customIntegration.configure(token, config);
} else if (process.env.CLIENT_ID && process.env.CLIENT_SECRET && process.env.PORT) {
    //Treat this as an app
    var app = require('./lib/apps');
    var controller = app.configure(process.env.PORT, process.env.CLIENT_ID, process.env.CLIENT_SECRET, config, onInstallation);
} else {
    console.log('Error: If this is a custom integration, please specify TOKEN in the environment. If this is an app, please specify CLIENTID, CLIENTSECRET, and PORT in the environment');
    process.exit(1);
}

/**
 * A demonstration for how to handle websocket events. In this case, just log when we have and have not
 * been disconnected from the websocket. In the future, it would be super awesome to be able to specify
 * a reconnect policy, and do reconnections automatically. In the meantime, we aren't going to attempt reconnects,
 * WHICH IS A B0RKED WAY TO HANDLE BEING DISCONNECTED. So we need to fix this.
 *
 * TODO: fixed b0rked reconnect behavior
 */
// Handle events related to the websocket connection to Slack
controller.on('rtm_open', function (bot) {
    console.log('** The RTM api just connected!');
});

controller.on('rtm_close', function (bot) {
    console.log('** The RTM api just closed');
    // you may want to attempt to re-open
});

/**
 * Core bot logic goes here!
 */
// BEGIN EDITING HERE!
var runHappening = false;
var runList = [];

controller.on('bot_channel_join', function (bot, message) {
    bot.reply(message, "I'm here!")
});

controller.hears('hello', 'direct_message', function (bot, message) {
    bot.reply(message, 'Hello!');
});

controller.hears('start', 'direct_mention', function(bot, message) {

    if (runHappening) {
        return bot.reply(message, 'Already gathering requests for a run in' + runChannel);
    }

    bot.reply(message, 'Holy La Croix! <@' + message.user + '> is going for a Pop-a-Top run. Who  <@here> has a request? Tell me what you want and I will let them know!');
    runHappening = true;
    console.log('===runHappening = ' + runHappening);
    console.log(message);
});

controller.hears('echo', 'direct_mention', function(bot, messsage) {
    bot.reply(message, '...echo');
    console.log('========Message ' + message);
});

//When the run is ended, collect runList into a string format, return it to user that owns the run
//TODO: Add metadata to the runList array containing owner, channel, etc.
controller.hears('end', 'direct_mention', function(bot, message) {
    if (!runHappening) {
        return bot.reply(message, 'Nobody is on a run right now. Start a new run with `start`');
    }

    runHappening = false;
    console.log('===runHappening = ' + runHappening);
    str = JSON.stringify(runList[0]);
    console.log('===runList = ' + str);

    bot.reply(message, 'The run is now over!');

    bot.startConversation(message, function(err,convo){
        convo.ask('<@' + message.user + '> want to see the list?', [{
            pattern: bot.utterances.yes,
            callback: function(response, convo) {
                console.log('====runList = ');
                console.log(runList[0]);

                //Initialize empty listString array
                var listString = [];

//////////////// I'm confused here now. What I want to do is take all the entries in runList and get them ready to be spat out at the run owner in the format NAME1: request1, request2, request3 **NEWLINE** NAME2: request1, request2
//////////////// Ultimately I need one string that has the results parsed into a single string, complete with escaped linebreaks to pass to bot.say

                //Loop through runList and convert entries into strings
                for (var i = 0; i < runList.length; i++) {

                    //Create a variable that contains the object to push into
                    var x = {user: message.user, requests: runList[i].requests.join(', ')};

                    //Use .push() to add anything to an array
                  listString.push(x);
                    bot.reply(message, (listString));
                }

                console.log('===Heard yes, output runList object');
                console.log('===Output listString= ' + listString);
                convo.next();
            }
        }, {
            pattern: bot.utterances.no,
            callback: function(response,convo) {
                bot.say({channel: message.channel, text: 'Okey Dokey. That was fun, see you later!'});
                // runModel.clearStatuses();
                console.log('Heard no')
                convo.next();
            }
        }]);
    });
});

/*runList = [
  {user: 'Em', requests: ['pamp mouse']}
]
*/
controller.hears('(.*)', 'direct_mention, direct_message', function(bot, message) {
    if (runHappening) {
        gatherRequest(bot, message);
    }
});

function gatherRequest(bot, message) {
    console.log('===request = ' + message.text);
    bot.reply(message, 'Got it! Thanks <@' + message.user + '>');
    addDesire(message);
    function addDesire(message){
        if (runList === []) {
            var pushy = {user: message.user, requests: [message.text]};
        console.log(pushy);
        runList.push(pushy);
        console.log('===addDesire: runlist = [] so add first entry');
        console.log(runList[0]);
        }
      for (var i = 0; i < runList.length; i++) {

    //Check if the current user already has an entry in runList under their user
      if (runList[i].user === message.user) {

        //If so, .push() the text of their message into the requests array
        runList[i].requests.push(message.text);
        console.log('===addDesire: user already exists in runList! Pushing their request into the requests array for their user');
      }

      //If not, .push() a new Object into runList with their user and request
      else {

        //Create a variable pushy to hold the object we are going to push into runList
        var pushy = {user: message.user, requests: [message.text]};
        console.log(pushy);
        runList.push(pushy);
      }
    }};

    console.log('===Pushing request to runList');

   /* runModel.addRequest({
        request: message.text,
        user: message.user
    });
    */

}
<commit_msg>took addDesire() out of gatherRequest() and put it into global<commit_after>/**
 * Configure the persistence options
 */

var config = {};
if (process.env.MONGOLAB_URI) {
    var BotkitStorage = require('botkit-storage-mongo');
    config = {
        storage: BotkitStorage({mongoUri: process.env.MONGOLAB_URI}),
    };
} else {
    config = {
        json_file_store: ((process.env.TOKEN)?'./db_slack_bot_ci/':'./db_slack_bot_a/'), //use a different name if an app or CI
    };
}

/**
 * Are being run as an app or a custom integration? The initialization will differ, depending
 */

if (process.env.TOKEN || process.env.SLACK_TOKEN) {
    //Treat this as a custom integration
    var customIntegration = require('./lib/custom_integrations');
    var token = (process.env.TOKEN) ? process.env.TOKEN : process.env.SLACK_TOKEN;
    var controller = customIntegration.configure(token, config);
} else if (process.env.CLIENT_ID && process.env.CLIENT_SECRET && process.env.PORT) {
    //Treat this as an app
    var app = require('./lib/apps');
    var controller = app.configure(process.env.PORT, process.env.CLIENT_ID, process.env.CLIENT_SECRET, config, onInstallation);
} else {
    console.log('Error: If this is a custom integration, please specify TOKEN in the environment. If this is an app, please specify CLIENTID, CLIENTSECRET, and PORT in the environment');
    process.exit(1);
}

/**
 * A demonstration for how to handle websocket events. In this case, just log when we have and have not
 * been disconnected from the websocket. In the future, it would be super awesome to be able to specify
 * a reconnect policy, and do reconnections automatically. In the meantime, we aren't going to attempt reconnects,
 * WHICH IS A B0RKED WAY TO HANDLE BEING DISCONNECTED. So we need to fix this.
 *
 * TODO: fixed b0rked reconnect behavior
 */
// Handle events related to the websocket connection to Slack
controller.on('rtm_open', function (bot) {
    console.log('** The RTM api just connected!');
});

controller.on('rtm_close', function (bot) {
    console.log('** The RTM api just closed');
    // you may want to attempt to re-open
});

/**
 * Core bot logic goes here!
 */
// BEGIN EDITING HERE!
var runHappening = false;
var runList = [];

controller.on('bot_channel_join', function (bot, message) {
    bot.reply(message, "I'm here!")
});

controller.hears('hello', 'direct_message', function (bot, message) {
    bot.reply(message, 'Hello!');
});

controller.hears('start', 'direct_mention', function(bot, message) {

    if (runHappening) {
        return bot.reply(message, 'Already gathering requests for a run in' + runChannel);
    }

    bot.reply(message, 'Holy La Croix! <@' + message.user + '> is going for a Pop-a-Top run. Who  <@here> has a request? Tell me what you want and I will let them know!');
    runHappening = true;
    console.log('===runHappening = ' + runHappening);
    console.log(message);
});

controller.hears('echo', 'direct_mention', function(bot, messsage) {
    bot.reply(message, '...echo');
    console.log('========Message ' + message);
});

//When the run is ended, collect runList into a string format, return it to user that owns the run
//TODO: Add metadata to the runList array containing owner, channel, etc.
controller.hears('end', 'direct_mention', function(bot, message) {
    if (!runHappening) {
        return bot.reply(message, 'Nobody is on a run right now. Start a new run with `start`');
    }

    runHappening = false;
    console.log('===runHappening = ' + runHappening);
    str = JSON.stringify(runList[0]);
    console.log('===runList = ' + str);

    bot.reply(message, 'The run is now over!');

    bot.startConversation(message, function(err,convo){
        convo.ask('<@' + message.user + '> want to see the list?', [{
            pattern: bot.utterances.yes,
            callback: function(response, convo) {
                console.log('====runList = ');
                console.log(runList[0]);

                //Initialize empty listString array
                var listString = [];

//////////////// I'm confused here now. What I want to do is take all the entries in runList and get them ready to be spat out at the run owner in the format NAME1: request1, request2, request3 **NEWLINE** NAME2: request1, request2
//////////////// Ultimately I need one string that has the results parsed into a single string, complete with escaped linebreaks to pass to bot.say

                //Loop through runList and convert entries into strings
                for (var i = 0; i < runList.length; i++) {

                    //Create a variable that contains the object to push into
                    var x = {user: message.user, requests: runList[i].requests.join(', ')};

                    //Use .push() to add anything to an array
                  listString.push(x);
                    bot.reply(message, (listString));
                }

                console.log('===Heard yes, output runList object');
                console.log('===Output listString= ' + listString);
                convo.next();
            }
        }, {
            pattern: bot.utterances.no,
            callback: function(response,convo) {
                bot.say({channel: message.channel, text: 'Okey Dokey. That was fun, see you later!'});
                // runModel.clearStatuses();
                console.log('Heard no')
                convo.next();
            }
        }]);
    });
});

/*runList = [
  {user: 'Em', requests: ['pamp mouse']}
]
*/
controller.hears('(.*)', 'direct_mention, direct_message', function(bot, message) {
    if (runHappening) {
        gatherRequest(bot, message);
    }
});

function gatherRequest(bot, message) {
    console.log('===request = ' + message.text);
    bot.reply(message, 'Got it! Thanks <@' + message.user + '>');
    addDesire(message);

    console.log('===Pushing request to runList');

   /* runModel.addRequest({
        request: message.text,
        user: message.user
    });
    */

};

    function addDesire(message){
        if (runList === []) {
            var pushy = {user: message.user, requests: [message.text]};
        console.log(pushy);
        runList.push(pushy);
        console.log('===addDesire: runlist = [] so add first entry');
        console.log(runList[0]);
        }

      for (var i = 0; i < runList.length; i++) {

    //Check if the current user already has an entry in runList under their user
      if (runList[i].user === message.user) {

        //If so, .push() the text of their message into the requests array
        runList[i].requests.push(message.text);
        console.log('===addDesire: user already exists in runList! Pushing their request into the requests array for their user');
      }

      //If not, .push() a new Object into runList with their user and request
      else {

        //Create a variable pushy to hold the object we are going to push into runList
        var pushy = {user: message.user, requests: [message.text]};
        console.log(pushy);
        runList.push(pushy);
      }
    }}
<|endoftext|>


<commit_before>/*jslint node: true */
'use strict';

/**
 * Module dependencies
 */

var Resource = require('deployd/lib/resource'),
	Session = require('deployd/lib/session'),
	util = require('util'),
	multiparty = require('multiparty'),
	fs = require('fs'),
	path = require('path'),
	gm = require('gm').subClass({imageMagick: true}),
	AWS = require('aws-sdk'),
	Promise = require('bluebird');
/**
 * Module setup.
 */

function ImageWrangler(name, options) {
	Resource.apply(this, arguments);
	if (this.config.accessKey && this.config.accessSecret && this.config.bucket) {
		AWS.config.update({
			accessKeyId: this.config.accessKey,
			secretAccessKey: this.config.accessSecret,
			bucket: this.config.bucket,
			region: this.config.region
		});
	}

}
util.inherits(ImageWrangler, Resource);

ImageWrangler.prototype.clientGeneration = true;

ImageWrangler.events = ['Post', 'File', 'Saving', 'Saved'];

ImageWrangler.basicDashboard = {
	settings: [{
		name: 'accessKey',
		type: 'text',
		description: 'The AWS access key id'
	}, {
		name: 'accessSecret',
		type: 'text',
		description: 'The AWS secret access key'
	}, {
		name: 'region',
		type: 'text',
		description: 'The AWS region'
	}, {
		name: 'tasks',
		type: 'textarea',
		description: 'JSON object detailing the image specs to be created for each image uploaded to this endpoint'
	}, {
		name: 'bucket',
		type: 'text',
	}, {
		name: 'basePath',
		type: 'text',
		description: 'base url for where someone could GET the file off the bucket (cloud front url if you are using that)'
	}, {
		name: 'publicRead',
		type: 'checkbox',
		description: 'when files are uploaded to your bucket, automatically set public read access?'
	}, {
		name: 'internalOnly',
		type: 'checkbox',
		description: 'Only allow internal scripts to send email'
	}, {
		name: 'imageQuality',
		type: 'text',
		description: '0-100 (default 95)'
	}]
};

function cleanupPath(path) {
	return path.replace('//', '/'); // replace double slash with single slash
}

ImageWrangler.prototype.process = function(ctx) {
	var wrangler = this;
	var req = ctx.req;
	var resizeTasks = JSON.parse(this.config.tasks);
	var parts = ctx.url.split('/').filter(function(p) {
		return p;
	});

	if (!resizeTasks[parts[0]]) {
		return ctx.done("invalid upload scope");
	}
	resizeTasks = resizeTasks[parts[0]];

	var subDirPath = '';
	if (parts.length > 0) subDirPath = parts.join('/');

	var form = new multiparty.Form();
	var remaining = 0;
	var files = [];
	var error;

	var responseObject = {};
	var cleanseFilename = function(incomingFilename) {
		//console.log("incoming filename: " + incomingFilename);
		var filename = incomingFilename;
		var extension = null;
		if (incomingFilename.indexOf('.') != -1) {
			var pieces = incomingFilename.split('.');
			extension = pieces.pop();
			filename = pieces.join('.');
		}
		//console.log("filename: " + filename);
		//console.log('extension: ' + extension);
		filename = filename.replace(/\s+/g, '-').toLowerCase(); //converst space to dash
		//console.log('replaced spaces with dashes: ' + filename);
		filename = filename.replace(/[^a-z0-9_\-]/gi, ''); // drop all other funny business
		//console.log('dropped bad characters: ' + filename);
		if (extension) {
			//console.log('completed result: ' + filename + '.' + extension);
			return filename + '.' + extension;
		}
		return filename;
	};
	var resizeFile = function(part, buffer) {
		function next(task, savedFile) {
			var size = task ? task.suffix : "original";
			responseObject[size] = wrangler.config.basePath + savedFile.replace(/^\/+/, "");
			resizeFile(part, buffer);
		}

		if (resizeTasks.length > 0) {
			var task = resizeTasks.pop();
			//console.log('task: ' + JSON.stringify(task));

			var output = cleanseFilename(part.filename).split('.');
			var outputName = output[0] + '-' + task.suffix + '.' + output[1];

			var quality = 95;
			if (wrangler.config.imageQuality) {
				quality = wrangler.config.imageQuality;
			}
			var completionBlock = function(err, stream) {
				if (!err) {
					wrangler.uploadFile(ctx, {
						task: task,
						originalFilename: part.filename,
						originalPath: subDirPath,
						filename: '/' + subDirPath + '/' + outputName,
						mime: part.headers["content-type"]
					}, stream, next);
				} else {
					//console.log(' error writing: ' + err);
					ctx.done(err);
				}
			};

			var resizeImage = function() {
				if (task.crop) {
					gm(buffer)
						.quality(quality)
						.autoOrient()
						.resize(task.width, task.height, '^')
						.gravity('Center')
						.extent(task.width, task.height)
						.stream(function(err, stdout, stderr) {
							completionBlock(err, stdout);
						});
				} else {
					gm(buffer)
						.quality(quality)
						.autoOrient()
						.flatten()
						.resize(task.width, task.height, '>')
						.stream(function(err, stdout, stderr) {
							completionBlock(err, stdout);
						});
				}
			};
			var resizeVectorial = function() {

				if (task.crop) {
					gm(buffer)
						.in("-colorspace", "srgb")
						.density(300,300)
						.bitdepth(8)
						.strip()
						.quality(quality)
						//.flatten()
						.resize(task.width, task.height, '^')
						.gravity('Center')
						.extent(task.width, task.height)
						.setFormat("PNG")
						.stream(function(err, stdout, stderr) {
							completionBlock(err, stdout);
						});
				} else {
					gm(buffer)
						.in("-colorspace", "srgb")
						.density(300,300)
						.bitdepth(8)
						.strip()
						.quality(quality)
						//.flatten()
						.resize(task.width, task.height, '>')
						.setFormat("PNG")
						.stream(function(err, stdout, stderr) {
							completionBlock(err, stdout);
						});
				}
			};

			gm(buffer).format(function(err, value) {
				if (err) {
					ctx.done(err);
					return;
				}

				if ((/EPT|PS/i).test(value)) {
					resizeVectorial();
				} else {
					resizeImage();
				}

			});
		} else {
			if (req.headers.referer) {
				ctx.done(null, responseObject);
			} else {
				ctx.done(null, files);
			}
		}
	};

	form.on('part', function(part) {
		remaining++;
		//write original version to s3 for safe keeping
		var output = cleanseFilename(part.filename).split('.');
		var outputName = output[0] + '-original.' + output[1];

		var readPromise = wrangler.readStream(part).catch(function(err) {
			return ctx.done(err);
		});

		function uploadOriginalFile(path) {
			readPromise.then(function(buffer){
				wrangler.uploadFile(ctx, {
					originalFilename: part.filename,
					originalPath: subDirPath,
					filename: path,
					mime: part.headers["content-type"]
				}, buffer, function(task, savedFile) {
					var size = task ? task.suffix : "original";
					responseObject[size] = wrangler.config.basePath + savedFile.replace(/^\/+/, "");
					resizeFile(part, buffer);
				});
			});
		}

		if (wrangler.events.File) {
			var domain = {
				data: {
					originalFilename: part.filename,
					path: subDirPath,
					filename: outputName,
					headers: part.headers,
					bytesExpected: part.bytesExpected
				}
			};
			wrangler.events.File.run(ctx, domain, function(err) {
				if (err) {
					part.resume();
					return ctx.done(err);
				}
				uploadOriginalFile(cleanupPath('/' + domain.data.path + '/' + domain.data.filename));
			});
		} else {
			uploadOriginalFile(cleanupPath('/' + subDirPath + '/' + outputName));
		}

	});
	form.on('error', function(err) {
		ctx.done(err);
		error = err;
	});

	form.parse(req);
	req.resume();
};

/**
 * Module methodes
 */

ImageWrangler.prototype.handle = function(ctx, next) {
	var req = ctx.req;
	var domain = {
		url: ctx.url
	};
	var wrangler = this;

	if (!this.config.basePath) this.config.basePath = '';

	if (!ctx.req.internal && this.config.internalOnly) {
		return ctx.done({
			statusCode: 403,
			message: 'Forbidden'
		});
	}

	if (req.method === 'POST' && !req.internal && req.headers['content-type'].indexOf('multipart/form-data') === 0) {
		if (wrangler.events.Post) {
			wrangler.events.Post.run(ctx, {}, function(err) {
				if (err) return ctx.done(err);
				wrangler.process(ctx);
			});
		} else {
			wrangler.process(ctx);
		}
		return;
	}

	next();
};

ImageWrangler.prototype.uploadFile = function(ctx, config, stream, fn) {
	var wrangler = this;
	//console.log('filename:' + filename);
	//console.log('mime:' + mime);

	function uploadFn(domain) {
		var s3config = {
			Bucket: wrangler.config.bucket,
			Key: domain.data.filename.replace(/^\/+/, ""),
			ContentType: domain.data.mime,
			Body: stream
		};
		if (wrangler.config.publicRead) {
			s3config.ACL = 'public-read';
		}

		var upload = new AWS.S3.ManagedUpload({params: s3config});
		upload.send(function(err, data) {
			if (err) return ctx.done(err);
			if (wrangler.events.Saved) {
				wrangler.events.Saved.run(ctx, {
					data: {
						task: config.task,
						originalFilename: config.originalFilename,
						originalPath: config.originalPath,
						savedFilename: domain.data.filename,
						mime: domain.data.mime,
						baseUrl: wrangler.config.basePath
					}
				}, function(err) {
					if (err) return ctx.done(err);
					fn(config.task, domain.data.filename);
				});
			} else {
				fn(config.task, domain.data.filename);
			}
		});
	}

	var domain = {
		data: {
			task: config.task,
			originalFilename: config.originalFilename,
			originalPath: config.originalPath,
			filename: config.filename,
			mime: config.mime
		}
	};
	if (wrangler.events.Saving) {
		wrangler.events.Saving.run(ctx, domain, function(err) {
			if (err) return ctx.done(err);
			uploadFn(domain);
		});
	} else {
		uploadFn(domain);
	}
};

ImageWrangler.prototype.readStream = function(stream) {
	return new Promise(function(resolve, reject) {
		var buffer = [];
		stream.on('data', function(data) {
			buffer.push(data);
		}).on('end', function() {
			resolve(Buffer.concat(buffer));
		}).on('error', function(err) {
			reject(err);
		});
	});
};

/**
 * Module export
 */

module.exports = ImageWrangler;
<commit_msg>Add trim.<commit_after>/*jslint node: true */
'use strict';

/**
 * Module dependencies
 */

var Resource = require('deployd/lib/resource'),
	Session = require('deployd/lib/session'),
	util = require('util'),
	multiparty = require('multiparty'),
	fs = require('fs'),
	path = require('path'),
	gm = require('gm').subClass({imageMagick: true}),
	AWS = require('aws-sdk'),
	Promise = require('bluebird');
/**
 * Module setup.
 */

function ImageWrangler(name, options) {
	Resource.apply(this, arguments);
	if (this.config.accessKey && this.config.accessSecret && this.config.bucket) {
		AWS.config.update({
			accessKeyId: this.config.accessKey,
			secretAccessKey: this.config.accessSecret,
			bucket: this.config.bucket,
			region: this.config.region
		});
	}

}
util.inherits(ImageWrangler, Resource);

ImageWrangler.prototype.clientGeneration = true;

ImageWrangler.events = ['Post', 'File', 'Saving', 'Saved'];

ImageWrangler.basicDashboard = {
	settings: [{
		name: 'accessKey',
		type: 'text',
		description: 'The AWS access key id'
	}, {
		name: 'accessSecret',
		type: 'text',
		description: 'The AWS secret access key'
	}, {
		name: 'region',
		type: 'text',
		description: 'The AWS region'
	}, {
		name: 'tasks',
		type: 'textarea',
		description: 'JSON object detailing the image specs to be created for each image uploaded to this endpoint'
	}, {
		name: 'bucket',
		type: 'text',
	}, {
		name: 'basePath',
		type: 'text',
		description: 'base url for where someone could GET the file off the bucket (cloud front url if you are using that)'
	}, {
		name: 'publicRead',
		type: 'checkbox',
		description: 'when files are uploaded to your bucket, automatically set public read access?'
	}, {
		name: 'internalOnly',
		type: 'checkbox',
		description: 'Only allow internal scripts to send email'
	}, {
		name: 'imageQuality',
		type: 'text',
		description: '0-100 (default 95)'
	}]
};

function cleanupPath(path) {
	return path.replace('//', '/'); // replace double slash with single slash
}

ImageWrangler.prototype.process = function(ctx) {
	var wrangler = this;
	var req = ctx.req;
	var resizeTasks = JSON.parse(this.config.tasks);
	var parts = ctx.url.split('/').filter(function(p) {
		return p;
	});

	if (!resizeTasks[parts[0]]) {
		return ctx.done("invalid upload scope");
	}
	resizeTasks = resizeTasks[parts[0]];

	var subDirPath = '';
	if (parts.length > 0) subDirPath = parts.join('/');

	var form = new multiparty.Form();
	var remaining = 0;
	var files = [];
	var error;

	var responseObject = {};
	var cleanseFilename = function(incomingFilename) {
		//console.log("incoming filename: " + incomingFilename);
		var filename = incomingFilename;
		var extension = null;
		if (incomingFilename.indexOf('.') != -1) {
			var pieces = incomingFilename.split('.');
			extension = pieces.pop();
			filename = pieces.join('.');
		}
		//console.log("filename: " + filename);
		//console.log('extension: ' + extension);
		filename = filename.replace(/\s+/g, '-').toLowerCase(); //converst space to dash
		//console.log('replaced spaces with dashes: ' + filename);
		filename = filename.replace(/[^a-z0-9_\-]/gi, ''); // drop all other funny business
		//console.log('dropped bad characters: ' + filename);
		if (extension) {
			//console.log('completed result: ' + filename + '.' + extension);
			return filename + '.' + extension;
		}
		return filename;
	};
	var resizeFile = function(part, buffer) {
		function next(task, savedFile) {
			var size = task ? task.suffix : "original";
			responseObject[size] = wrangler.config.basePath + savedFile.replace(/^\/+/, "");
			resizeFile(part, buffer);
		}

		if (resizeTasks.length > 0) {
			var task = resizeTasks.pop();
			//console.log('task: ' + JSON.stringify(task));

			var output = cleanseFilename(part.filename).split('.');
			var outputName = output[0] + '-' + task.suffix + '.' + output[1];

			var quality = 95;
			if (wrangler.config.imageQuality) {
				quality = wrangler.config.imageQuality;
			}
			var completionBlock = function(err, stream) {
				if (!err) {
					wrangler.uploadFile(ctx, {
						task: task,
						originalFilename: part.filename,
						originalPath: subDirPath,
						filename: '/' + subDirPath + '/' + outputName,
						mime: part.headers["content-type"]
					}, stream, next);
				} else {
					//console.log(' error writing: ' + err);
					ctx.done(err);
				}
			};

			var resizeImage = function() {
				if (task.crop) {
					gm(buffer)
						.quality(quality)
						.autoOrient()
						.resize(task.width, task.height, '^')
						.gravity('Center')
						.extent(task.width, task.height)
						.stream(function(err, stdout, stderr) {
							completionBlock(err, stdout);
						});
				} else {
					gm(buffer)
						.quality(quality)
						.autoOrient()
						.flatten()
						.resize(task.width, task.height, '>')
						.stream(function(err, stdout, stderr) {
							completionBlock(err, stdout);
						});
				}
			};
			var resizeVectorial = function() {

				if (task.crop) {
					gm(buffer)
						.in("-colorspace", "srgb")
						.density(300,300)
						.bitdepth(8)
						.strip()
						.trim()
						.quality(quality)
						//.flatten()
						.resize(task.width, task.height, '^')
						.gravity('Center')
						.extent(task.width, task.height)
						.setFormat("PNG")
						.stream(function(err, stdout, stderr) {
							completionBlock(err, stdout);
						});
				} else {
					gm(buffer)
						.in("-colorspace", "srgb")
						.density(300,300)
						.bitdepth(8)
						.strip()
						.trim()
						.quality(quality)
						//.flatten()
						.resize(task.width, task.height, '>')
						.setFormat("PNG")
						.stream(function(err, stdout, stderr) {
							completionBlock(err, stdout);
						});
				}
			};

			gm(buffer).format(function(err, value) {
				if (err) {
					ctx.done(err);
					return;
				}

				if ((/EPT|PS/i).test(value)) {
					resizeVectorial();
				} else {
					resizeImage();
				}

			});
		} else {
			if (req.headers.referer) {
				ctx.done(null, responseObject);
			} else {
				ctx.done(null, files);
			}
		}
	};

	form.on('part', function(part) {
		remaining++;
		//write original version to s3 for safe keeping
		var output = cleanseFilename(part.filename).split('.');
		var outputName = output[0] + '-original.' + output[1];

		var readPromise = wrangler.readStream(part).catch(function(err) {
			return ctx.done(err);
		});

		function uploadOriginalFile(path) {
			readPromise.then(function(buffer){
				wrangler.uploadFile(ctx, {
					originalFilename: part.filename,
					originalPath: subDirPath,
					filename: path,
					mime: part.headers["content-type"]
				}, buffer, function(task, savedFile) {
					var size = task ? task.suffix : "original";
					responseObject[size] = wrangler.config.basePath + savedFile.replace(/^\/+/, "");
					resizeFile(part, buffer);
				});
			});
		}

		if (wrangler.events.File) {
			var domain = {
				data: {
					originalFilename: part.filename,
					path: subDirPath,
					filename: outputName,
					headers: part.headers,
					bytesExpected: part.bytesExpected
				}
			};
			wrangler.events.File.run(ctx, domain, function(err) {
				if (err) {
					part.resume();
					return ctx.done(err);
				}
				uploadOriginalFile(cleanupPath('/' + domain.data.path + '/' + domain.data.filename));
			});
		} else {
			uploadOriginalFile(cleanupPath('/' + subDirPath + '/' + outputName));
		}

	});
	form.on('error', function(err) {
		ctx.done(err);
		error = err;
	});

	form.parse(req);
	req.resume();
};

/**
 * Module methodes
 */

ImageWrangler.prototype.handle = function(ctx, next) {
	var req = ctx.req;
	var domain = {
		url: ctx.url
	};
	var wrangler = this;

	if (!this.config.basePath) this.config.basePath = '';

	if (!ctx.req.internal && this.config.internalOnly) {
		return ctx.done({
			statusCode: 403,
			message: 'Forbidden'
		});
	}

	if (req.method === 'POST' && !req.internal && req.headers['content-type'].indexOf('multipart/form-data') === 0) {
		if (wrangler.events.Post) {
			wrangler.events.Post.run(ctx, {}, function(err) {
				if (err) return ctx.done(err);
				wrangler.process(ctx);
			});
		} else {
			wrangler.process(ctx);
		}
		return;
	}

	next();
};

ImageWrangler.prototype.uploadFile = function(ctx, config, stream, fn) {
	var wrangler = this;
	//console.log('filename:' + filename);
	//console.log('mime:' + mime);

	function uploadFn(domain) {
		var s3config = {
			Bucket: wrangler.config.bucket,
			Key: domain.data.filename.replace(/^\/+/, ""),
			ContentType: domain.data.mime,
			Body: stream
		};
		if (wrangler.config.publicRead) {
			s3config.ACL = 'public-read';
		}

		var upload = new AWS.S3.ManagedUpload({params: s3config});
		upload.send(function(err, data) {
			if (err) return ctx.done(err);
			if (wrangler.events.Saved) {
				wrangler.events.Saved.run(ctx, {
					data: {
						task: config.task,
						originalFilename: config.originalFilename,
						originalPath: config.originalPath,
						savedFilename: domain.data.filename,
						mime: domain.data.mime,
						baseUrl: wrangler.config.basePath
					}
				}, function(err) {
					if (err) return ctx.done(err);
					fn(config.task, domain.data.filename);
				});
			} else {
				fn(config.task, domain.data.filename);
			}
		});
	}

	var domain = {
		data: {
			task: config.task,
			originalFilename: config.originalFilename,
			originalPath: config.originalPath,
			filename: config.filename,
			mime: config.mime
		}
	};
	if (wrangler.events.Saving) {
		wrangler.events.Saving.run(ctx, domain, function(err) {
			if (err) return ctx.done(err);
			uploadFn(domain);
		});
	} else {
		uploadFn(domain);
	}
};

ImageWrangler.prototype.readStream = function(stream) {
	return new Promise(function(resolve, reject) {
		var buffer = [];
		stream.on('data', function(data) {
			buffer.push(data);
		}).on('end', function() {
			resolve(Buffer.concat(buffer));
		}).on('error', function(err) {
			reject(err);
		});
	});
};

/**
 * Module export
 */

module.exports = ImageWrangler;
<|endoftext|>


<commit_before>var hubiquitus = require('hubiquitus-core');
var logger = hubiquitus.logger('hubiquitus:addons:ping');
var _ = require('lodash');
var http = require('http');
var url = require('url');

module.exports = function (name, addr) {
  if (!_.isString(name)) throw new TypeError('Name must be a string');
  if (!_.isString(addr)) throw new TypeError('Addr must be an http URL');

  logger.info('ping configured with name: ' + name + '; addr: ' + addr);
  hubiquitus.addActor('hping', function () {
    if (this.started) return;
    this.started = true;

    var endpoint = url.resolve(addr, '/ping/' + name);
    (function tick() {
      logger.trace('ping...');
      http.get(endpoint, function (res) {
        setTimeout(tick, 500);
      }).on('error', function (err) {
        logger.warn('ping failed', err);
      });
    })();
  }, {name: name, addr: addr});

  hubiquitus.send('hping-master', 'hping');
};
<commit_msg>ping improvement : wait for response or error to ping again; disable keepalive<commit_after>var hubiquitus = require('hubiquitus-core');
var logger = hubiquitus.logger('hubiquitus:addons:ping');
var _ = require('lodash');
var http = require('http');
var url = require('url');

module.exports = function (name, addr) {
  if (!_.isString(name)) throw new TypeError('Name must be a string');
  if (!_.isString(addr)) throw new TypeError('Addr must be an http URL');

  logger.info('ping configured with name: ' + name + '; addr: ' + addr);
  hubiquitus.addActor('hping', function () {
    if (this.started) return logger.warn('already emitting...');
    this.started = true;

    var endpoint = url.resolve(addr, '/ping/' + hubiquitus.properties.ID + '/' + name);

    var tick = (function tick() {
      logger.trace('ping [' + endpoint + ']...');
      http.get(endpoint, onRes)
        .on('socket', onSock)
        .on('error', onErr);
      return tick;
    })();

    function onRes(res) {
      logger.trace('ping ack : ' + res.statusCode + ' !');
      setTimeout(tick, 30000);
    }

    function onSock(sock) {
      sock.emit('agentRemove');
    }

    function onErr(err) {
      logger.warn('ping failed', err);
      setTimeout(tick, 30000);
    }

  }, {name: name, addr: addr});

  hubiquitus.send('hping-master', 'hping');
};
<|endoftext|>


<commit_before>var _ = require('lodash');
var browserSync = require('browser-sync');

function BrowserSyncPlugin(browserSyncOptions, options) {
  var self = this;

  var defaultOptions = {
    reload: true,
    name: 'bs-webpack-plugin',
    callback: undefined
  };

  self.browserSyncOptions = _.extend({}, browserSyncOptions);
  self.options = _.extend({}, defaultOptions, options);

  self.browserSync = browserSync.create(self.options.name);
  self.webpackIsWatching = false;
  self.browserSyncIsRunning = false;
}

BrowserSyncPlugin.prototype.apply = function (compiler) {
  var self = this;

  compiler.plugin('watch-run', function (watching, callback) {
    self.webpackIsWatching = true;
    callback(null, null);
  });

  compiler.plugin('done', function (stats) {
    if (self.webpackIsWatching) {
      if (self.browserSyncIsRunning) {
        if (self.options.reload) {
          self.browserSync.reload();
        }
      } else {
        if (_.isFunction(self.options.callback)) {
          self.browserSync.init(self.browserSyncOptions, self.options.callback);
        } else {
          self.browserSync.init(self.browserSyncOptions);
        }

        self.browserSyncIsRunning = true;
      }
    }
  });
};

module.exports = BrowserSyncPlugin;
<commit_msg>Add browserSync notification upon compilation step<commit_after>var _ = require('lodash');
var browserSync = require('browser-sync');

function BrowserSyncPlugin(browserSyncOptions, options) {
  var self = this;

  var defaultOptions = {
    reload: true,
    name: 'bs-webpack-plugin',
    callback: undefined
  };

  self.browserSyncOptions = _.extend({}, browserSyncOptions);
  self.options = _.extend({}, defaultOptions, options);

  self.browserSync = browserSync.create(self.options.name);
  self.webpackIsWatching = false;
  self.browserSyncIsRunning = false;
}

BrowserSyncPlugin.prototype.apply = function (compiler) {
  var self = this;

  compiler.plugin('watch-run', function (watching, callback) {
    self.webpackIsWatching = true;
    callback(null, null);
  });

  compiler.plugin('compilation', function () {
    self.browserSync.notify('Rebuilding');
  });

  compiler.plugin('done', function (stats) {
    if (self.webpackIsWatching) {
      if (self.browserSyncIsRunning) {
        if (self.options.reload) {
          self.browserSync.reload();
        }
      } else {
        if (_.isFunction(self.options.callback)) {
          self.browserSync.init(self.browserSyncOptions, self.options.callback);
        } else {
          self.browserSync.init(self.browserSyncOptions);
        }

        self.browserSyncIsRunning = true;
      }
    }
  });
};

module.exports = BrowserSyncPlugin;
<|endoftext|>


<commit_before>const BPromise = require('bluebird');
const { utils, dataTypes, cms } = require('../directus');
const R = require('ramda');

const fetchLinkLogo = link => BPromise.props({
  link: R.prop('link', link),
  name: R.prop('name', link),
  logo: cms.getActiveFile(R.prop('logo', link))
    .then(cms.createImageUrl),
});

const fetchSponsorsLogo = sponsor => BPromise.props({
  name: R.prop('name', sponsor),
  website: R.prop('website', sponsor),
  logo: cms.getActiveFile(R.prop('logo', sponsor))
    .then(cms.createImageUrl),
});

const fetchSubPages = () => cms.getActiveItems(dataTypes.categories.table)
  .then(R.prop('data'))
  .then(R.filter(R.compose(R.not, R.isEmpty, R.path(['subpages', 'data']))))
  .then(R.map(R.pick(['title', 'slug', 'subpages'])))
  .then(R.map(category => R.merge(category, {
    subpages: R.map(R.pick(['title', 'slug', 'priority']), category.subpages.data),
  })));

const fetchSubPageBySlug = (slug) => {
  const options = {
    filters: {
      slug: {
        '=': slug,
      },
    },
  };

  return cms.getActiveItems(dataTypes.subpages.table, options)
    .then(utils.pickFirstResultData)
    .then(R.pick(['title', 'slug', 'text', 'category_id']));
};

const fetchFooter = () => cms.getActiveItems(dataTypes.footer.table)
  .then(utils.pickFirstResultData)
  .then(R.pick(['contact_info', 'other_links', 'social_media_buttons']))
  .then((footer) => {
    if (R.isEmpty(footer)) {
      return footer;
    }
    return BPromise.props({
      contact_info: footer.contact_info,
      other_links: R.map(R.pick(['title', 'link']), footer.other_links.data),
      social_media_buttons: BPromise.map(
        footer.social_media_buttons.data,
        fetchLinkLogo),
    });
  });

const fetchSponsors = () => cms.getActiveItems(dataTypes.sponsors.table)
  .then(R.prop('data'))
  .then(sponsors => BPromise.map(sponsors, fetchSponsorsLogo));

module.exports = {
  fetchSubPages,
  fetchSubPageBySlug,
  fetchFooter,
  fetchSponsors,
};
<commit_msg>Send category ids for pages<commit_after>const BPromise = require('bluebird');
const { utils, dataTypes, cms } = require('../directus');
const R = require('ramda');

const fetchLinkLogo = link => BPromise.props({
  link: R.prop('link', link),
  name: R.prop('name', link),
  logo: cms.getActiveFile(R.prop('logo', link))
    .then(cms.createImageUrl),
});

const fetchSponsorsLogo = sponsor => BPromise.props({
  name: R.prop('name', sponsor),
  website: R.prop('website', sponsor),
  logo: cms.getActiveFile(R.prop('logo', sponsor))
    .then(cms.createImageUrl),
});

const fetchSubPages = () => cms.getActiveItems(dataTypes.categories.table)
  .then(R.prop('data'))
  .then(R.filter(R.compose(R.not, R.isEmpty, R.path(['subpages', 'data']))))
  .then(R.map(R.pick(['id', 'title', 'slug', 'subpages'])))
  .then(R.map(category => R.merge(category, {
    subpages: R.map(R.pick(['category_id', 'title', 'slug', 'priority']), category.subpages.data),
  })));

const fetchSubPageBySlug = (slug) => {
  const options = {
    filters: {
      slug: {
        '=': slug,
      },
    },
  };

  return cms.getActiveItems(dataTypes.subpages.table, options)
    .then(utils.pickFirstResultData)
    .then(R.pick(['title', 'slug', 'text', 'category_id']));
};

const fetchFooter = () => cms.getActiveItems(dataTypes.footer.table)
  .then(utils.pickFirstResultData)
  .then(R.pick(['contact_info', 'other_links', 'social_media_buttons']))
  .then((footer) => {
    if (R.isEmpty(footer)) {
      return footer;
    }
    return BPromise.props({
      contact_info: footer.contact_info,
      other_links: R.map(R.pick(['title', 'link']), footer.other_links.data),
      social_media_buttons: BPromise.map(
        footer.social_media_buttons.data,
        fetchLinkLogo),
    });
  });

const fetchSponsors = () => cms.getActiveItems(dataTypes.sponsors.table)
  .then(R.prop('data'))
  .then(sponsors => BPromise.map(sponsors, fetchSponsorsLogo));

module.exports = {
  fetchSubPages,
  fetchSubPageBySlug,
  fetchFooter,
  fetchSponsors,
};
<|endoftext|>


<commit_before>'use strict'

const express = require('express')
const bodyParser = require('body-parser')
const config = require('./config')
const app = express()

var rp = require('request-promise');
var cronJob = require('cron').CronJob;

const LINENotifyToken = process.env.LINENotifyToken
const LINENotifySIGTToken = process.env.LINENotifySIGTToken
const OMGPairID = '26'
const BTCPairID = '1'
const ETHPairID = '21'
const ZECPairID = '8'

app.set('port', (process.env.PORT || config.PORT))

app.use(bodyParser.urlencoded({extended: false}))

app.use(bodyParser.json())

app.get('/', function (req, res) {
  res.send('Meeaaww');
})

app.get('/meaw', function (req, res) {
  publish();
  res.status(200).send('Meaaawww');
})

function publish() {
  publishOMG()
  publishSIGT()
}

function publishOMG() {
  var bxOptions = {
    uri: 'https://bx.in.th/api/',
    json: true
  };

  rp(bxOptions)
    .then(function ( marketdata ) {
        console.log(marketdata[OMGPairID]);

        let omgPair = marketdata[OMGPairID];
        let btcPair = marketdata[BTCPairID];
        let ethPair = marketdata[ETHPairID];
        let zecPair = marketdata[ZECPairID];

        notifyToGroup(omgPair, btcPair, ethPair, zecPair);
    })
    .catch(function (err) {
        console.log(err);
    });
}

function publishSIGT() {
  var sigtOptions = {
    uri: 'https://api.coinmarketcap.com/v1/ticker/signatum/',
    json: true
  };

  rp(sigtOptions)
    .then(function ( sigt ) {
        console.log(sigt[0]);
        notifyToSIGTGroup(sigt[0])
    })
    .catch(function (err) {
        console.log(err);
    });
}

function messageGenerator( omg, btc, eth, zec ) {
  let change = omg['change'];
  let lastPrice = omg['last_price'];
  let volumeIn24HR = omg['volume_24hours'];
  let volumeBids = omg['orderbook']['bids'];
  let volumeAsks = omg['orderbook']['asks'];

  let omglastPriceMSG = `1 OMG : ${lastPrice} THB\n`;
  let omgChangeMSG = `Change : ${change}%\n`;
  let omgVolume24MSG = `Volume24HR : ${volumeIn24HR} OMG\n`;
  let omgBidsMSG = `Highest buy: ${volumeBids.highbid} THB\n`;
  let omgAsksMSG = `Lowest sell: ${volumeAsks.highbid} THB\n`;

  let spliter = '- - - - - - - - - - - - - -\n'

  let btcLastPriceMSG = `1 BTC : ${btc.last_price} THB\n`;
  let ethLastPriceMSG = `1 ETH : ${eth.last_price} THB\n`;

  let zecPrice = (btc.last_price * zec.last_price).toFixed(2);
  let zecLastPriceMSG = `1 ZEC : ${zecPrice} THB\n`

  let theEnd = '≧◡≦';

  return `✿OMG✿\n` + omglastPriceMSG + omgChangeMSG + omgVolume24MSG
  + omgBidsMSG + omgAsksMSG + spliter + btcLastPriceMSG + ethLastPriceMSG + zecLastPriceMSG
  + theEnd;
}

function messageSIGTGenerator( sigt ) {
  let price_usd = ( sigt.price_usd * 33.28 )
  return `✿SIGT✿\n` + `1 SIGT\n${price_usd} THB\n` + `${sigt.price_btc} BTC\n` + `------------`
}

function notifyToGroup( omg, btc, eth, zec ) {
  var message = messageGenerator(omg, btc, eth, zec);

  var headers = {
    'User-Agent':       'AzukiChan/0.0.1',
    'Content-Type':     'application/x-www-form-urlencoded'
  }

  var options = {
    'url': 'https://notify-api.line.me/api/notify',
    'method': 'POST',
    'headers': headers,
    'auth': {
       'bearer': LINENotifyToken
    },
    'form': {
       'message': message
    }
  }

  rp(options)
    .then(function ( result ) {
        console.log('publish success');
    })
    .catch(function (err) {
        console.log(err);
    });
}

function notifyToSIGTGroup( sigt ) {
  var message = messageSIGTGenerator(sigt);

  var headers = {
    'User-Agent':       'AzukiChan/0.0.1',
    'Content-Type':     'application/x-www-form-urlencoded'
  }

  var options = {
    'url': 'https://notify-api.line.me/api/notify',
    'method': 'POST',
    'headers': headers,
    'auth': {
       'bearer': LINENotifySIGTToken
    },
    'form': {
       'message': message
    }
  }

  rp(options)
    .then(function ( result ) {
        console.log('publish success');
    })
    .catch(function (err) {
        console.log(err);
    });
}

app.listen(app.get('port'), () => {
  console.log(`Running Crypty on port : ${app.get('port')}`)

  var job = new cronJob({
    cronTime: '0 */20 * * * *',
    onTick: function() {
      // Publish every 20 min
      publish();
    },
    start: false,
    timeZone: 'Asia/Bangkok'
  });

  job.start();
})
<commit_msg>Unpublished omg from bx (temporary)<commit_after>'use strict'

const express = require('express')
const bodyParser = require('body-parser')
const config = require('./config')
const app = express()

var rp = require('request-promise');
var cronJob = require('cron').CronJob;

const LINENotifyToken = process.env.LINENotifyToken
const LINENotifySIGTToken = process.env.LINENotifySIGTToken
const OMGPairID = '26'
const BTCPairID = '1'
const ETHPairID = '21'
const ZECPairID = '8'

app.set('port', (process.env.PORT || config.PORT))

app.use(bodyParser.urlencoded({extended: false}))

app.use(bodyParser.json())

app.get('/', function (req, res) {
  res.send('Meeaaww');
})

app.get('/meaw', function (req, res) {
  publish();
  res.status(200).send('Meaaawww');
})

function publish() {
  // publishOMG()
  publishSIGT()
}

function publishOMG() {
  var bxOptions = {
    uri: 'https://bx.in.th/api/',
    json: true
  };

  rp(bxOptions)
    .then(function ( marketdata ) {
        console.log(marketdata[OMGPairID]);

        let omgPair = marketdata[OMGPairID];
        let btcPair = marketdata[BTCPairID];
        let ethPair = marketdata[ETHPairID];
        let zecPair = marketdata[ZECPairID];

        notifyToGroup(omgPair, btcPair, ethPair, zecPair);
    })
    .catch(function (err) {
        console.log(err);
    });
}

function publishSIGT() {
  var sigtOptions = {
    uri: 'https://api.coinmarketcap.com/v1/ticker/signatum/',
    json: true
  };

  rp(sigtOptions)
    .then(function ( sigt ) {
        console.log(sigt[0]);
        notifyToSIGTGroup(sigt[0])
    })
    .catch(function (err) {
        console.log(err);
    });
}

function messageGenerator( omg, btc, eth, zec ) {
  let change = omg['change'];
  let lastPrice = omg['last_price'];
  let volumeIn24HR = omg['volume_24hours'];
  let volumeBids = omg['orderbook']['bids'];
  let volumeAsks = omg['orderbook']['asks'];

  let omglastPriceMSG = `1 OMG : ${lastPrice} THB\n`;
  let omgChangeMSG = `Change : ${change}%\n`;
  let omgVolume24MSG = `Volume24HR : ${volumeIn24HR} OMG\n`;
  let omgBidsMSG = `Highest buy: ${volumeBids.highbid} THB\n`;
  let omgAsksMSG = `Lowest sell: ${volumeAsks.highbid} THB\n`;

  let spliter = '- - - - - - - - - - - - - -\n'

  let btcLastPriceMSG = `1 BTC : ${btc.last_price} THB\n`;
  let ethLastPriceMSG = `1 ETH : ${eth.last_price} THB\n`;

  let zecPrice = (btc.last_price * zec.last_price).toFixed(2);
  let zecLastPriceMSG = `1 ZEC : ${zecPrice} THB\n`

  let theEnd = '≧◡≦';

  return `✿OMG✿\n` + omglastPriceMSG + omgChangeMSG + omgVolume24MSG
  + omgBidsMSG + omgAsksMSG + spliter + btcLastPriceMSG + ethLastPriceMSG + zecLastPriceMSG
  + theEnd;
}

function messageSIGTGenerator( sigt ) {
  let price_usd = ( sigt.price_usd * 33.28 )
  return `✿SIGT✿\n` + `1 SIGT\n${price_usd} THB\n` + `${sigt.price_btc} BTC\n` + `------------`
}

function notifyToGroup( omg, btc, eth, zec ) {
  var message = messageGenerator(omg, btc, eth, zec);

  var headers = {
    'User-Agent':       'AzukiChan/0.0.1',
    'Content-Type':     'application/x-www-form-urlencoded'
  }

  var options = {
    'url': 'https://notify-api.line.me/api/notify',
    'method': 'POST',
    'headers': headers,
    'auth': {
       'bearer': LINENotifyToken
    },
    'form': {
       'message': message
    }
  }

  rp(options)
    .then(function ( result ) {
        console.log('publish success');
    })
    .catch(function (err) {
        console.log(err);
    });
}

function notifyToSIGTGroup( sigt ) {
  var message = messageSIGTGenerator(sigt);

  var headers = {
    'User-Agent':       'AzukiChan/0.0.1',
    'Content-Type':     'application/x-www-form-urlencoded'
  }

  var options = {
    'url': 'https://notify-api.line.me/api/notify',
    'method': 'POST',
    'headers': headers,
    'auth': {
       'bearer': LINENotifySIGTToken
    },
    'form': {
       'message': message
    }
  }

  rp(options)
    .then(function ( result ) {
        console.log('publish success');
    })
    .catch(function (err) {
        console.log(err);
    });
}

app.listen(app.get('port'), () => {
  console.log(`Running Crypty on port : ${app.get('port')}`)

  var job = new cronJob({
    cronTime: '0 */20 * * * *',
    onTick: function() {
      // Publish every 20 min
      publish();
    },
    start: false,
    timeZone: 'Asia/Bangkok'
  });

  job.start();
})
<|endoftext|>


<commit_before>"use strict";

var modernizr = require("modernizr");

module.exports = function (config) {
    var cb = this.async();

    modernizr.build(JSON.parse(config), function (output) {
        cb(null, output);
    });
};
<commit_msg>Exposing Modernizr as a module<commit_after>"use strict";

var modernizr = require("modernizr");

function wrapOutput(output) {
  // Exposing Modernizr as a module.
  return ';(function(window){\n' +
            output + '\n' +
            'module.exports = window.Modernizr;\n' +
          '})(window);';
}

module.exports = function (config) {
    var cb = this.async();

    modernizr.build(JSON.parse(config), function (output) {
        cb(null, wrapOutput(output));
    });
};
<|endoftext|>