<commit_before>/**
 * CouchDB base class/resource definition.
 * This file should be inherited by all CouchDB models that want to leverage
 * CouchDB's power in rocket.
 */

var crypto = require('crypto')
  , _ = require('underscore')
  , lingo = require('lingo')
  , cradle = require('cradle')
  , async = require('async')
  ;

var oo = require('../utils/oo')
  , namespace = require('../utils/namespace')
  , BaseResource = require('./base_resource')
  ;

/******************************************************************************
 * CONSTANTS
 */

var ROCKET_NAMESPACE = 'rocket';

/******************************************************************************
 * Default connection parameters
 */
CouchDBResource.connection = {
    host: 'localhost'
  , port: 5984
  , options: {
      raw: true
    , cache: false
    , auth: null
    }
  };

/******************************************************************************
 * Default _design documents                                     *** SYNCD ***
 */
CouchDBResource.ddocs = [
    {
      _id: '_design/rocket'
    , lists: {}
    , shows: {}
    , updates: {
        in_place: function(doc, req) {
          var oo  = require('rocket/oo')
            , ret
            ;

          if(doc !== null) {
            oo.__extends(doc, req.query, { overwrite: true });
            ret = doc;
          }else{
            ret = req.query;
          }

          return [ret, JSON.stringify(ret)];
        }
      }
    , validate_doc_update: function(newDoc, oldDoc, userCtx) {

        if(newDoc._deleted
        || typeof newDoc.doc_type === 'undefined'
        || newDoc.doc_type === null
        || newDoc.doc_type === ''
        ){
          return;
        }

        var schema = require('rocket/schema/' + newDoc.doc_type);

        for(var member in schema) {

          if(typeof schema[member] !== 'undefined'
          && schema[member] !== null) {

            var validator;
            var optional;
            var prefix;

            if(typeof schema[member] === 'string') {

              validator = require('rocket/validators/' + schema[member]) || null;

            }else if(typeof schema[member] === 'object') {

              alias = schema[member].alias;
              prefix = schema[member].prefix;
              optional = schema[member].optional;
              validator = (schema[member].validate ? require('rocket/validators/' + schema[member].validate) : null);

            }

            var value = newDoc[member];

            if(typeof value !== 'undefined'
            && value !== null) {
              if(alias) {
                continue;
              }

              if(prefix) {
                if(value.substr(0, prefix.length) !== prefix) {
                  throw({ invalid: member + '[' + value + '] must have prefix [' + prefix + ']' + '\n' + JSON.stringify(newDoc) });
                }else{
                  value = value.substr(prefix.length);
                }
              }

              if(validator) {
                validator(member, value);
              }else{
                continue;
              }
            }else if(optional || alias){
              continue;
            }else{
              throw({ invalid: member + ' can\'t be missing or null' });
            }
          }
        }
      }
    , views: {
       all: {
          map: function(doc) { emit(doc._id, doc); }
        }
      }
    }
  ];

/******************************************************************************
 * Default _security document                                    *** SYNCD ***
 */
CouchDBResource._security = {
    admins: {
        names: ["admin"]
      , roles: []
      }
  , readers: {
        names: ["admin"]
      , roles: []
      }
  };

/******************************************************************************
 * Utils functions
 */
function setProperties(dst, src, synced) {

  var synced = typeof synced !== 'undefined' ? synced : true;

  if(! dst.synced)  { Object.defineProperty(dst, 'synced', {value: {}}); }
  if(! dst.values)    { Object.defineProperty(dst, 'values', {value: {}}); }

  function createSetter(prop) {
    return function(v) {
      dst.synced[prop] = dst.synced[prop] && dst.values[prop] === v;
      dst.values[prop] = v;
    }
  }

  function createGetter(prop) {
    return function() { return dst.values[prop] };
  }

  for(var prop in src) {

    if(src.propertyIsEnumerable(prop) === false
    || dst.__lookupGetter__(prop)
    || dst.__lookupSetter__(prop)
    ){
      continue;
    }

    var val = src[prop];
    delete src[prop];
    Object.defineProperty(dst, prop, { enumerable: true,  configurable: true, get: createGetter(prop), set: createSetter(prop) });
    dst.synced[prop] = synced;
    dst.values[prop] = val;
  }
}

function updateCache(obj, newValues) {
  if(obj.__db.cache.store[obj._id]) {
    obj.__db.cache.store[obj._id].document = newValues;
    obj.__db.cache.store[obj._id].attime = Date.now();
  }
}

function timestamp(obj) {

  var current_time = Date.now();

  if(typeof obj.creation_date === 'undefined'
  || obj.creation_date === null
  ){
    obj.creation_date = current_time;
  }

  obj.modification_date = current_time;
}

function set_doc_type(obj, doc_type) {
  if(typeof obj.doc_type === 'undefined'
  || obj.doc_type === null
  || obj.doc_type === ''
  || !obj.propertyIsEnumerable('doc_type')
  || obj.doc_type !== doc_type
  ){
    obj.doc_type = doc_type;
  }
}

function objectify(obj, options, cons, cb) {
  var objects = []
    ;

  if(Array.isArray(obj)){
    cons = (Array.isArray(cons) ? cons : [cons]);

    for(var i = 0, ii = obj.length; i < ii; i++) {
      var constructor =  cons[i % cons.length]
        ;

      if(options.view) {
        if(options.include_doc) {
          obj[i].doc = new constructor(obj[i].doc);
        }else{
          obj[i].value = new constructor(obj[i].value);
        }
      }else{
        obj[i] = new constructor(obj[i])
      }
    }
    cb(null, obj);
  }else{
    //single object...
    cb(null, new cons(obj));
  }
}

/******************************************************************************
 * Resource Prototype Functions (used to create models)
 */
CouchDBResource.prototype = {
    save: function save_CouchDBResourceInstance(callback) {
      var that = this
      ;

      timestamp(this);
      set_doc_type(this, this.doc_type);

      this.__db.save(this._id, this._rev, this, function(err,res) {
        if(err){
          callback(err);
        }else{
          setProperties(that, that);
          callback(null, res);
        }
      });
    }
  , update: function update_CouchDBResourceInstance(callback) {
      var modz = {}
        , that = this
        ;

      timestamp(this);
      set_doc_type(this, this.doc_type);

      for(var k in this) {
        if(this.propertyIsEnumerable(k) === false) {
          continue;
        }

        if(! this.synced[k]) {
          modz[k] = this[k];
        }
      }

      if(modz !== {}) {
        this.__db.update('rocket/in_place', this._id, modz, function(err){
          if(err){
            callback(err);
          }else{
            setProperties(that, that);
            updateCache(that, that.values);
            callback.apply(that, Array.prototype.slice.apply(arguments));
          }
        });
      }else{
        callback(null, '');
      }
    }
  , destroy: function destroy_CouchDBResourceInstance(callback) {
      this.__db.remove(this._id, function(err) { callback(err); });
    }
  , reload: function reload_CouchDBResourceInstance(callback) {
      var that = this;

      this.__db.get(this._id, function(err, doc) {
        if(err) {
          callback(err);
        }else{
          setProperties(that, doc);
          callback(null, that);
        }
      });

    }
  , exists: function exists_CouchDBResourceInstance() {}
  };

/******************************************************************************
 * Resource Factory/Constructor Functions
 */
var factoryFunctions = {
    initialize: function initialize_CouchDBResource(model_name, callback) {
      var that = this
        , doc_type = namespace.extractName(model_name.toLowerCase(), { suffix: '_document' })
        ;

      //Initialize connection object
      that.__connection = new cradle.Connection(
          that.connection.host
        , that.connection.port
        , that.connection.options
        );

      //Infer DB name from file name unless specified
      if(typeof that.db_name !== 'undefined' && that.db_name !== null){
        that.__db_name = that.db_name;
      }else{
        that.__db_name = lingo.en.pluralize(doc_type);
      }

      //setup db object
      that.__db = that.__connection.database(that.__db_name);
      that.prototype.__db  = that.__db;

      that.prototype.doc_type  = doc_type;

      //Create db if it doesn't exists. Harmless otherwise.
      that.__db.create();

      //prepare ddoc if it exists
      if(that.ddoc) {
        that.ddoc._id = that.ddoc._id || '_design/' + doc_type;
        that.ddocs.push(that.ddoc);
      }

      async.parallel([
        function(callback) { async.forEach(that.ddocs, syncDoc, callback); }
      , function(callback) { that.__db._save('_security', false, that._security, callback); }
      ], callback);

      function fctToString(obj) {
       for(var key in obj) {
          if(typeof obj[key] === 'function') {
            obj[key] = obj[key].toString();
          }else if(typeof obj[key] === 'object' && obj[key] !== null) {
            arguments.callee(obj[key]);
          }
        }
      }

      function syncDoc(docObj, callback) {

        //create the `rocket` namespace in the design doc
        docObj[ROCKET_NAMESPACE] = {};

        //add the validators to the design doc
        docObj[ROCKET_NAMESPACE].validators = oo.__extends({}, that.validators);

        //add the schema to the design doc
        docObj[ROCKET_NAMESPACE].schema = {};
        docObj[ROCKET_NAMESPACE].schema[doc_type] = 'module.exports = ' + JSON.stringify(that.schema);

        //convert all functions to strings
        fctToString(docObj);

        //make all validators available through commonJS' `require`
        for(var f in docObj[ROCKET_NAMESPACE].validators) {
          docObj[ROCKET_NAMESPACE].validators[f] = 'module.exports = ' + docObj[ROCKET_NAMESPACE].validators[f];
        }

        //make all the oo functions available through commonJS' `require`
        docObj[ROCKET_NAMESPACE].oo = fs.readFileSync(path.join(__dirname, '../utils/oo.js'), 'utf8');

        that.__db.get(docObj._id, checkAndUpdate);

        function checkAndUpdate(err, doc) {

          doc = doc || {};

          var oldDocJSON = JSON.stringify(doc);

          //extend the DB doc with the current doc
          oo.__deepExtends(doc, docObj, {overwrite: true});

          //docObj to a JSON string
          var docJSON = JSON.stringify(doc);

          if(err) {
            if(err.error === 'not_found'){
              that.__db.save(doc._id, doc, callback);
            }else{
              console.log(('xxx [CouchDBResource] ERROR id: ' + doc._id + ' ' + require('util').inspect(err)).red);
              callback(err);
            }
          }else{

            if(oldDocJSON !== docJSON) {
              that.__db.save(doc._id, doc._rev, doc, callback);
            }else{
              callback(null);
            }
          }
        };
      };
    }
  , create: function create_CouchDBResource(obj, callback) {
      var constructor = this.prototype.constructor
        , obj = (obj instanceof constructor ? obj : new constructor(obj))
        ;

      obj.save(callback);
    }
  , save: function save_CouchDBResource(obj, callback) {
      var constructor = this.prototype.constructor
        , obj = (obj instanceof constructor ? obj : new constructor(obj))
        ;

      obj.save(callback);
    }
  , get: function get_CouchDBResource(_id, callback) {
      var that = this;
      this.__db.get(_id, function(err, doc){ objectify(doc, { view: false }, that.prototype.constructor, callback); });
    }
  , destroy: function destroy_CouchDBResource(_id, callback) {
      this.__db.remove(_id, callback);
    }
  , all: function all_CouchDBResource(args) {
      var args_array = Array.prototype.slice.call(arguments)
        ;

      args_array.unshift('rocket/all');

      this.view.apply(this, args_array);
    }
  , view: function view_CouchDBResource() {
      var args_array    = Array.prototype.slice.call(arguments)
        , view          = args_array.shift()
        , callback      = args_array.pop()
        , params        = (
                             typeof args_array[0] === 'object'
                          && args_array[0]
                          && ! Array.isArray(args_array[0])
                          ? args_array.shift()
                          : {}
                          )
        , constructors  = (
                             typeof args_array[0] === 'object'
                          && args_array[0]
                          && Array.isArray(args_array[0])
                          ? args_array.shift()
                          : this.prototype.constructor
                          )
        ;

      if(view.indexOf('/') === -1){ view = this.prototype.doc_type + '/' + view; }

      //call with our callback to objectify the result
      this.__db.view(view, params, function(err, res){
        if(err){ console.log(err); callback(err); return; }
        objectify(res.rows, {view: true, include_docs: params.include_docs}, constructors, function(err, objects){
          res.rows = objects;
          callback(err, res);
        });
      });
    }
  };

oo.__extends(CouchDBResource, factoryFunctions, {overwrite: true});

/******************************************************************************
 * CouchDBResource's Constructor
 */
function CouchDBResource(obj) {
  arguments.callee.__super__.call(this, obj);
  setProperties(this, this);
};

oo.inherits(CouchDBResource, BaseResource);

//Finally export the CouchDBResource Object
module.exports = CouchDBResource;
<commit_msg>added myView. Cradle  this is the beginning of you no more in rocket. b***<commit_after>/**
 * CouchDB base class/resource definition.
 * This file should be inherited by all CouchDB models that want to leverage
 * CouchDB's power in rocket.
 */

var crypto = require('crypto')
  , _ = require('underscore')
  , lingo = require('lingo')
  , cradle = require('cradle')
  , async = require('async')
  ;

var oo = require('../utils/oo')
  , namespace = require('../utils/namespace')
  , BaseResource = require('./base_resource')
  ;

/******************************************************************************
 * CONSTANTS
 */

var ROCKET_NAMESPACE = 'rocket';

/******************************************************************************
 * Default connection parameters
 */
CouchDBResource.connection = {
    host: 'localhost'
  , port: 5984
  , options: {
      raw: true
    , cache: false
    , auth: null
    }
  };

/******************************************************************************
 * Default _design documents                                     *** SYNCD ***
 */
CouchDBResource.ddocs = [
    {
      _id: '_design/rocket'
    , lists: {}
    , shows: {}
    , updates: {
        in_place: function(doc, req) {
          var oo  = require('rocket/oo')
            , ret
            ;

          if(doc !== null) {
            oo.__extends(doc, req.query, { overwrite: true });
            ret = doc;
          }else{
            ret = req.query;
          }

          return [ret, JSON.stringify(ret)];
        }
      }
    , validate_doc_update: function(newDoc, oldDoc, userCtx) {

        if(newDoc._deleted
        || typeof newDoc.doc_type === 'undefined'
        || newDoc.doc_type === null
        || newDoc.doc_type === ''
        ){
          return;
        }

        var schema = require('rocket/schema/' + newDoc.doc_type);

        for(var member in schema) {

          if(typeof schema[member] !== 'undefined'
          && schema[member] !== null) {

            var validator;
            var optional;
            var prefix;

            if(typeof schema[member] === 'string') {

              validator = require('rocket/validators/' + schema[member]) || null;

            }else if(typeof schema[member] === 'object') {

              alias = schema[member].alias;
              prefix = schema[member].prefix;
              optional = schema[member].optional;
              validator = (schema[member].validate ? require('rocket/validators/' + schema[member].validate) : null);

            }

            var value = newDoc[member];

            if(typeof value !== 'undefined'
            && value !== null) {
              if(alias) {
                continue;
              }

              if(prefix) {
                if(value.substr(0, prefix.length) !== prefix) {
                  throw({ invalid: member + '[' + value + '] must have prefix [' + prefix + ']' + '\n' + JSON.stringify(newDoc) });
                }else{
                  value = value.substr(prefix.length);
                }
              }

              if(validator) {
                validator(member, value);
              }else{
                continue;
              }
            }else if(optional || alias){
              continue;
            }else{
              throw({ invalid: member + ' can\'t be missing or null' });
            }
          }
        }
      }
    , views: {
       all: {
          map: function(doc) { emit(doc._id, doc); }
        }
      }
    }
  ];

/******************************************************************************
 * Default _security document                                    *** SYNCD ***
 */
CouchDBResource._security = {
    admins: {
        names: ["admin"]
      , roles: []
      }
  , readers: {
        names: ["admin"]
      , roles: []
      }
  };

/******************************************************************************
 * Utils functions
 */
function setProperties(dst, src, synced) {

  var synced = typeof synced !== 'undefined' ? synced : true;

  if(! dst.synced)  { Object.defineProperty(dst, 'synced', {value: {}}); }
  if(! dst.values)    { Object.defineProperty(dst, 'values', {value: {}}); }

  function createSetter(prop) {
    return function(v) {
      dst.synced[prop] = dst.synced[prop] && dst.values[prop] === v;
      dst.values[prop] = v;
    }
  }

  function createGetter(prop) {
    return function() { return dst.values[prop] };
  }

  for(var prop in src) {

    if(src.propertyIsEnumerable(prop) === false
    || dst.__lookupGetter__(prop)
    || dst.__lookupSetter__(prop)
    ){
      continue;
    }

    var val = src[prop];
    delete src[prop];
    Object.defineProperty(dst, prop, { enumerable: true,  configurable: true, get: createGetter(prop), set: createSetter(prop) });
    dst.synced[prop] = synced;
    dst.values[prop] = val;
  }
}

function updateCache(obj, newValues) {
  if(obj.__db.cache.store[obj._id]) {
    obj.__db.cache.store[obj._id].document = newValues;
    obj.__db.cache.store[obj._id].attime = Date.now();
  }
}

function timestamp(obj) {

  var current_time = Date.now();

  if(typeof obj.creation_date === 'undefined'
  || obj.creation_date === null
  ){
    obj.creation_date = current_time;
  }

  obj.modification_date = current_time;
}

function set_doc_type(obj, doc_type) {
  if(typeof obj.doc_type === 'undefined'
  || obj.doc_type === null
  || obj.doc_type === ''
  || !obj.propertyIsEnumerable('doc_type')
  || obj.doc_type !== doc_type
  ){
    obj.doc_type = doc_type;
  }
}

function objectify(obj, options, cons, cb) {
  var objects = []
    ;

  if(Array.isArray(obj)){
    cons = (Array.isArray(cons) ? cons : [cons]);

    for(var i = 0, ii = obj.length; i < ii; i++) {
      var constructor =  cons[i % cons.length]
        ;

      if(options.view) {
        if(options.include_doc) {
          obj[i].doc = new constructor(obj[i].doc);
        }else{
          obj[i].value = new constructor(obj[i].value);
        }
      }else{
        obj[i] = new constructor(obj[i])
      }
    }
    cb(null, obj);
  }else{
    //single object...
    cb(null, new cons(obj));
  }
}

/******************************************************************************
 * Resource Prototype Functions (used to create models)
 */
CouchDBResource.prototype = {
    save: function save_CouchDBResourceInstance(callback) {
      var that = this
      ;

      timestamp(this);
      set_doc_type(this, this.doc_type);

      this.__db.save(this._id, this._rev, this, function(err,res) {
        if(err){
          callback(err);
        }else{
          setProperties(that, that);
          callback(null, res);
        }
      });
    }
  , update: function update_CouchDBResourceInstance(callback) {
      var modz = {}
        , that = this
        ;

      timestamp(this);
      set_doc_type(this, this.doc_type);

      for(var k in this) {
        if(this.propertyIsEnumerable(k) === false) {
          continue;
        }

        if(! this.synced[k]) {
          modz[k] = this[k];
        }
      }

      if(modz !== {}) {
        this.__db.update('rocket/in_place', this._id, modz, function(err){
          if(err){
            callback(err);
          }else{
            setProperties(that, that);
            updateCache(that, that.values);
            callback.apply(that, Array.prototype.slice.apply(arguments));
          }
        });
      }else{
        callback(null, '');
      }
    }
  , destroy: function destroy_CouchDBResourceInstance(callback) {
      this.__db.remove(this._id, function(err) { callback(err); });
    }
  , reload: function reload_CouchDBResourceInstance(callback) {
      var that = this;

      this.__db.get(this._id, function(err, doc) {
        if(err) {
          callback(err);
        }else{
          setProperties(that, doc);
          callback(null, that);
        }
      });

    }
  , exists: function exists_CouchDBResourceInstance() {}
  };

/******************************************************************************
 * Resource Factory/Constructor Functions
 */
var factoryFunctions = {
    initialize: function initialize_CouchDBResource(model_name, callback) {
      var that = this
        , doc_type = namespace.extractName(model_name.toLowerCase(), { suffix: '_document' })
        ;

      //Initialize connection object
      that.__connection = new cradle.Connection(
          that.connection.host
        , that.connection.port
        , that.connection.options
        );

      //Infer DB name from file name unless specified
      if(typeof that.db_name !== 'undefined' && that.db_name !== null){
        that.__db_name = that.db_name;
      }else{
        that.__db_name = lingo.en.pluralize(doc_type);
      }

      //setup db object
      that.__db = that.__connection.database(that.__db_name);
      that.prototype.__db  = that.__db;

      that.prototype.doc_type  = doc_type;

      //Create db if it doesn't exists. Harmless otherwise.
      that.__db.create();

      //prepare ddoc if it exists
      if(that.ddoc) {
        that.ddoc._id = that.ddoc._id || '_design/' + doc_type;
        that.ddocs.push(that.ddoc);
      }

      async.parallel([
        function(callback) { async.forEach(that.ddocs, syncDoc, callback); }
      , function(callback) { that.__db._save('_security', false, that._security, callback); }
      ], callback);

      function fctToString(obj) {
       for(var key in obj) {
          if(typeof obj[key] === 'function') {
            obj[key] = obj[key].toString();
          }else if(typeof obj[key] === 'object' && obj[key] !== null) {
            arguments.callee(obj[key]);
          }
        }
      }

      function syncDoc(docObj, callback) {

        //create the `rocket` namespace in the design doc
        docObj[ROCKET_NAMESPACE] = {};

        //add the validators to the design doc
        docObj[ROCKET_NAMESPACE].validators = oo.__extends({}, that.validators);

        //add the schema to the design doc
        docObj[ROCKET_NAMESPACE].schema = {};
        docObj[ROCKET_NAMESPACE].schema[doc_type] = 'module.exports = ' + JSON.stringify(that.schema);

        //convert all functions to strings
        fctToString(docObj);

        //make all validators available through commonJS' `require`
        for(var f in docObj[ROCKET_NAMESPACE].validators) {
          docObj[ROCKET_NAMESPACE].validators[f] = 'module.exports = ' + docObj[ROCKET_NAMESPACE].validators[f];
        }

        //make all the oo functions available through commonJS' `require`
        docObj[ROCKET_NAMESPACE].oo = fs.readFileSync(path.join(__dirname, '../utils/oo.js'), 'utf8');

        that.__db.get(docObj._id, checkAndUpdate);

        function checkAndUpdate(err, doc) {

          doc = doc || {};

          var oldDocJSON = JSON.stringify(doc);

          //extend the DB doc with the current doc
          oo.__deepExtends(doc, docObj, {overwrite: true});

          //docObj to a JSON string
          var docJSON = JSON.stringify(doc);

          if(err) {
            if(err.error === 'not_found'){
              that.__db.save(doc._id, doc, callback);
            }else{
              console.log(('xxx [CouchDBResource] ERROR id: ' + doc._id + ' ' + require('util').inspect(err)).red);
              callback(err);
            }
          }else{

            if(oldDocJSON !== docJSON) {
              that.__db.save(doc._id, doc._rev, doc, callback);
            }else{
              callback(null);
            }
          }
        };
      };
    }
  , create: function create_CouchDBResource(obj, callback) {
      var constructor = this.prototype.constructor
        , obj = (obj instanceof constructor ? obj : new constructor(obj))
        ;

      obj.save(callback);
    }
  , save: function save_CouchDBResource(obj, callback) {
      var constructor = this.prototype.constructor
        , obj = (obj instanceof constructor ? obj : new constructor(obj))
        ;

      obj.save(callback);
    }
  , get: function get_CouchDBResource(_id, callback) {
      var that = this;
      this.__db.get(_id, function(err, doc){ objectify(doc, { view: false }, that.prototype.constructor, callback); });
    }
  , destroy: function destroy_CouchDBResource(_id, callback) {
      this.__db.remove(_id, callback);
    }
  , all: function all_CouchDBResource(args) {
      var args_array = Array.prototype.slice.call(arguments)
        ;

      args_array.unshift('rocket/all');

      this.view.apply(this, args_array);
    }
  , myView: function myView_CouchDBResource() {
      var args_array    = Array.prototype.slice.call(arguments)
      , view          = args_array.shift()
      , callback      = args_array.pop()
      , params        = (
                           typeof args_array[0] === 'object'
                        && args_array[0]
                        && ! Array.isArray(args_array[0])
                        ? args_array.shift()
                        : {}
                        )
      , params_array;

      for(var k in params) {
    	  v = params[k];

    	  params_array.push([
    	                      k
    	                    , '='
    	                    , JSON.stringify(v)
    	                    ].join('')
    	  );
      }

      var constructors  = (
                           typeof args_array[0] === 'object'
                        && args_array[0]
                        && Array.isArray(args_array[0])
                        ? args_array.shift()
                        : this.prototype.constructor
                        )
      , splitted_param = view.split('/')
      , get_options   = {
    	    host: this.connection.host
    	  , port: this.connection.port
    	  , path: [
    	           	'/'
	           	  , path.join(
    			        this.db_name
    			      , '_design'
    			      , (splitted_param.length === 1  ? this.prototype.doc_type : splitted_param[0])
    			      , '_view'
    			      , (splitted_param.length === 1  ? splitted_param[0] : splitted_param[1])
    	  		    )
    	  		  , '?'
    	  		  , params_array.join('&')
    	  		  ].join('')
        }
      ;

    console.log(get_options);
    if(view.indexOf('/') === -1){ view = this.prototype.doc_type + '/' + view; }

    //call with our callback to objectify the result
    /*this.__db.view(view, params, function(err, res){
      if(err){ console.log(err); callback(err); return; }
      objectify(res.rows, {view: true, include_docs: params.include_docs}, constructors, function(err, objects){
        res.rows = objects;
        callback(err, res);
      });
    });*/

    http.get(this.__connection, callback);
  }
  , view: function view_CouchDBResource() {
      var args_array    = Array.prototype.slice.call(arguments)
        , view          = args_array.shift()
        , callback      = args_array.pop()
        , params        = (
                             typeof args_array[0] === 'object'
                          && args_array[0]
                          && ! Array.isArray(args_array[0])
                          ? args_array.shift()
                          : {}
                          )
        , constructors  = (
                             typeof args_array[0] === 'object'
                          && args_array[0]
                          && Array.isArray(args_array[0])
                          ? args_array.shift()
                          : this.prototype.constructor
                          )
        ;

      if(view.indexOf('/') === -1){ view = this.prototype.doc_type + '/' + view; }

      //call with our callback to objectify the result
      this.__db.view(view, params, function(err, res){
        if(err){ console.log(err); callback(err); return; }
        objectify(res.rows, {view: true, include_docs: params.include_docs}, constructors, function(err, objects){
          res.rows = objects;
          callback(err, res);
        });
      });
    }
  };

oo.__extends(CouchDBResource, factoryFunctions, {overwrite: true});

/******************************************************************************
 * CouchDBResource's Constructor
 */
function CouchDBResource(obj) {
  arguments.callee.__super__.call(this, obj);
  setProperties(this, this);
};

oo.inherits(CouchDBResource, BaseResource);

//Finally export the CouchDBResource Object
module.exports = CouchDBResource;
<|endoftext|>


<commit_before>var mongoose = require( 'mongoose' );
var Schema   = mongoose.Schema;

var Block = new Schema(
{
    "number": {type: Number, index: {unique: true}},
    "hash": String,
    "parentHash": String,
    "nonce": String,
    "sha3Uncles": String,
    "logsBloom": String,
    "transactionsRoot": String,
    "stateRoot": String,
    "receiptRoot": String,
    "miner": String,
    "difficulty": String,
    "totalDifficulty": String,
    "size": Number,
    "extraData": String,
    "gasLimit": Number,
    "gasUsed": Number,
    "timestamp": Number,
    "uncles": [String],
    "txns":Number
});

var Contract = new Schema(
{
    "address": {type: String, index: {unique: true}},
    "creationTransaction": String,
    "contractName": String,
    "compilerVersion": String,
    "optimization": Boolean,
    "sourceCode": String,
    "abi": String,
    "byteCode": String
}, {collection: "Contract"});

var Transaction = new Schema(
{
    "hash": {type: String, index: {unique: true}},
    "nonce": Number,
    "blockHash": String,
    "blockNumber": Number,
    "transactionIndex": Number,
    "from": String,
    "to": String,
    "value": String,
    "gas": Number,
    "gasUsed": Number,
    "gasPrice": String,
    "timestamp": Number,
    "input": String
}, { strict: false });

mongoose.model('Block', Block);
mongoose.model('Contract', Contract);
mongoose.model('Transaction', Transaction);
module.exports.Block = mongoose.model('Block');
module.exports.Contract = mongoose.model('Contract');
module.exports.Transaction = mongoose.model('Transaction');
var options = { server: { socketOptions: { keepAlive: 300000, connectTimeoutMS: 30000 } },
                replset: { socketOptions: { keepAlive: 300000, connectTimeoutMS : 30000 } } };

mongoose.connect( 'mongodb://localhost/blockDB', options);
mongoose.set('debug', true);
<commit_msg>add index to blocknumber at transaction scheme<commit_after>var mongoose = require( 'mongoose' );
var Schema   = mongoose.Schema;

var Block = new Schema(
{
    "number": {type: Number, index: {unique: true}},
    "hash": String,
    "parentHash": String,
    "nonce": String,
    "sha3Uncles": String,
    "logsBloom": String,
    "transactionsRoot": String,
    "stateRoot": String,
    "receiptRoot": String,
    "miner": String,
    "difficulty": String,
    "totalDifficulty": String,
    "size": Number,
    "extraData": String,
    "gasLimit": Number,
    "gasUsed": Number,
    "timestamp": Number,
    "uncles": [String],
    "txns":Number
});

var Contract = new Schema(
{
    "address": {type: String, index: {unique: true}},
    "creationTransaction": String,
    "contractName": String,
    "compilerVersion": String,
    "optimization": Boolean,
    "sourceCode": String,
    "abi": String,
    "byteCode": String
}, {collection: "Contract"});

var Transaction = new Schema(
{
    "hash": {type: String, index: {unique: true}},
    "nonce": Number,
    "blockHash": String,
    "blockNumber":  {type: Number, index: {unique: true}},
    "transactionIndex": Number,
    "from": String,
    "to": String,
    "value": String,
    "gas": Number,
    "gasUsed": Number,
    "gasPrice": String,
    "timestamp": Number,
    "input": String
}, { strict: false });

mongoose.model('Block', Block);
mongoose.model('Contract', Contract);
mongoose.model('Transaction', Transaction);
module.exports.Block = mongoose.model('Block');
module.exports.Contract = mongoose.model('Contract');
module.exports.Transaction = mongoose.model('Transaction');
var options = { server: { socketOptions: { keepAlive: 300000, connectTimeoutMS: 30000 } },
                replset: { socketOptions: { keepAlive: 300000, connectTimeoutMS : 30000 } } };

mongoose.connect( 'mongodb://localhost/blockDB', options);
mongoose.set('debug', true);
<|endoftext|>


<commit_before>/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          ______     ______     ______   __  __     __     ______
          /\  == \   /\  __ \   /\__  _\ /\ \/ /    /\ \   /\__  _\
          \ \  __<   \ \ \/\ \  \/_/\ \/ \ \  _"-.  \ \ \  \/_/\ \/
          \ \_____\  \ \_____\    \ \_\  \ \_\ \_\  \ \_\    \ \_\
           \/_____/   \/_____/     \/_/   \/_/\/_/   \/_/     \/_/

This is a sample Slack bot built with Botkit.

This bot demonstrates many of the core features of Botkit:

* Connect to Slack using the real time API
* Receive messages based on "spoken" patterns
* Reply to messages
* Use the conversation system to ask questions
* Use the built in storage system to store and retrieve information
  for a user.

# RUN THE BOT:

  Get a Bot token from Slack:

    -> http://my.slack.com/services/new/bot

  Run your bot from the command line:

    token=<MY TOKEN> node bot.js

# USE THE BOT:

  Find your bot inside Slack to send it a direct message.

  Say: "Hello"

  The bot will reply "Hello!"

  Say: "who are you?"

  The bot will tell you its name, where it running, and for how long.

  Say: "Call me <nickname>"

  Tell the bot your nickname. Now you are friends.

  Say: "who am I?"

  The bot will tell you your nickname, if it knows one for you.

  Say: "shutdown"

  The bot will ask if you are sure, and then shut itself down.

  Make sure to invite your bot into other channels using /invite @<my bot>!

# EXTEND THE BOT:

  Botkit is has many features for building cool and useful bots!

  Read all about it here:

    -> http://howdy.ai/botkit

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//AVOID HEROKU BINDING ERROR
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.send('it is running\n');
}).listen(process.env.PORT || 5000);
//END AVOIDANCE

var Botkit = require('./lib/Botkit.js')
var os = require('os');
var http = require('follow-redirects').http;
var cheerio = require('cheerio');
var StringDecoder = require('string_decoder').StringDecoder;

function getOneAcross(def,cons, cb){
  var options = {
    host: 'www3.oneacross.com',
    path: '/cgi-bin/search_banner.cgi?c0='+encodeURIComponent(def)+'&p0='+ encodeURIComponent(cons)+'&s=+Go%21+'
  };
  console.log(def);
  console.log(cons);
  var result ='';
  var req = http.get(options, function(res) {
    console.log('STATUS: ' + res.statusCode);
    console.log('HEADERS: ' + JSON.stringify(res.headers));
    // Buffer the body entirely for processing as a whole.
    var bodyChunks = [];
    res.on('data', function(chunk) {
      // You can process streamed parts here...
      bodyChunks.push(chunk);
    });
    res.on('end', function() {
      var body = Buffer.concat(bodyChunks);
      $ = cheerio.load(body);
      var words = [];
      $('tt').each(function(i, elem) {
        // var thisWord = $(this).text();
        var starEmoji = ":star:";
        var stars = 0;
        $(this).parent().siblings().first().children().each(function(i, elem) {
          if ($(this).attr('src')=="/images/smallstarblack.gif"){
            stars++;
          }
        });
        // console.log(thisWord + ' ' + stars);

        words.push(starEmoji.repeat(stars) + $(this).text());
      });
      cb(words);
    })
  });
  req.on('error', function(e) {
    console.log('ERROR: ' + e.message);
    return "fail";
  });

  return result;
}

function getNutrimatic(query, cb){
  var options = {
    host: 'www.nutrimatic.org',
    path: '/?q='+query
  };
  console.log(query);
  var result ='';
  var req = http.get(options, function(res) {
    console.log('STATUS: ' + res.statusCode);
    console.log('HEADERS: ' + JSON.stringify(res.headers));
    //console.log('Body: ' + res.body);
    // Buffer the body entirely for processing as a whole.
    var body ='';
    res.setEncoding('utf8');
    res.on('data', function(chunk) {
      // You can process streamed parts here...
      //var textChunk = decoder.write(chunk);
      body = body.concat(chunk);
      //console.log(chunk);
    });
    res.on('end', function() {
      console.log(body);
      // var body = Buffer.concat(bodyChunks);
      $ = cheerio.load(body);
      console.log(body);
      var words = [];
      $('span').each(function(i, elem) {
        words.push($(this).text());
      });
      cb(words);
    })
  });
  req.on('error', function(e) {
    console.log('ERROR: ' + e.message);
    return "fail";
  });

  return result;
}

var controller = Botkit.slackbot({
  debug: false,
});

var bot = controller.spawn(
  {
    token:process.env.token
  }
).startRTM();

controller.hears(['hello','hi'],'direct_message,direct_mention,mention',function(bot,message) {

  bot.api.reactions.add({
    timestamp: message.ts,
    channel: message.channel,
    name: 'robot_face',
  },function(err,res) {
    if (err) {
      bot.botkit.log("Failed to add emoji reaction :(",err);
    }
  });

  controller.storage.users.get(message.user,function(err,user) {
    if (user && user.name) {
      bot.reply(message,"Hello " + user.name+"!!");
    } else {
      bot.reply(message,"Hello.");
    }
  });
})

controller.hears(['call me (.*)'],'direct_message,direct_mention,mention',function(bot,message) {
  var matches = message.text.match(/call me (.*)/i);
  var output = '';
  for (var i = 0; i < matches.length; i++) {
    output = output.concat(i, matches[i]);
  }
  var name = matches[1];
  controller.storage.users.get(message.user,function(err,user) {
    if (!user) {
      user = {
        id: message.user,
      }
    }
    user.name = name;
    controller.storage.users.save(user,function(err,id) {
      bot.reply(message,"Got it. I will call you " + output + " from now on.");
    })
  })
});

controller.hears(['what is my name','who am i'],'direct_message,direct_mention,mention',function(bot,message) {

  controller.storage.users.get(message.user,function(err,user) {
    if (user && user.name) {
      bot.reply(message,"Your name is " + user.name);
    } else {
      bot.reply(message,"I don't know yet!");
    }
  })
});

controller.hears(['shutdown'],'direct_message,direct_mention,mention',function(bot,message) {

  bot.startConversation(message,function(err,convo) {
    convo.ask("Are you sure you want me to shutdown?",[
      {
        pattern: bot.utterances.yes,
        callback: function(response,convo) {
          convo.say("Bye!");
          convo.next();
          setTimeout(function() {
            process.exit();
          },3000);
        }
      },
      {
        pattern: bot.utterances.no,
        default:true,
        callback: function(response,convo) {
          convo.say("*Phew!*");
          convo.next();
        }
      }
    ])
  })
})

controller.hears(['uptime','identify yourself','who are you','what is your name'],'direct_message,direct_mention,mention',function(bot,message) {

  var hostname = os.hostname();
  var uptime = formatUptime(process.uptime());

  bot.reply(message,':robot_face: I am a bot named <@' + bot.identity.name +'>. I have been running for ' + uptime + ' on ' + hostname + ".");

})

function formatUptime(uptime) {
  var unit = 'second';
  if (uptime > 60) {
    uptime = uptime / 60;
    unit = 'minute';
  }
  if (uptime > 60) {
    uptime = uptime / 60;
    unit = 'hour';
  }
  if (uptime != 1) {
    unit = unit +'s';
  }

  uptime = uptime + ' ' + unit;
  return uptime;
}

controller.hears(['hello','hi'],'direct_message,direct_mention,mention',function(bot,message) {

  bot.api.reactions.add({
    timestamp: message.ts,
    channel: message.channel,
    name: 'robot_face',
  },function(err,res) {
    if (err) {
      bot.botkit.log("Failed to add emoji reaction :(",err);
    }
  });

  controller.storage.users.get(message.user,function(err,user) {
    if (user && user.name) {
      bot.reply(message,"Hello " + user.name+"!!");
    } else {
      bot.reply(message,"Hello.");
    }
  });
})

//ONE ACROSS
controller.hears(['!OA (.*) ([a-zA-Z0-9?]*)'],'direct_message,direct_mention,mention,ambient',function(bot,message) {
  var matches = message.text.match(/!OA (.*) ([a-zA-Z0-9?]*)/i);

  var definition = matches[1];
  var constraint = matches[2];

  controller.storage.users.get(message.user,function(err,user) {
    if (!user) {
      user = {
        id: message.user,
      }
    }
    controller.storage.users.save(user,function(err,id) {
      function processWords(words){
        words.pop();
        words.pop();
        bot.reply(message,"Results: " + words.join(', '));
      }
      getOneAcross(definition, constraint, processWords);
    })
  })
});

//NUTRIMATIC
controller.hears(['!NM (.*)'],'direct_message,direct_mention,mention,ambient',function(bot,message) {
  var matches = message.text.match(/!NM (.*)/i);
  var query = matches[1];
  query = query.replace("<","<");
  query = query.replace(">",">");
  //query = query.replace(/ /g,"%20");
  //query = query.replace(/"/g,"%22");
  query = encodeURI(query);
  controller.storage.users.get(message.user,function(err,user) {
    if (!user) {
      user = {
        id: message.user,
      }
    }
    controller.storage.users.save(user,function(err,id) {
      function processQuery(query){
        numResults = 5;
        if (query.length < numResults){
          numResults = query.length;
        }
        if (numResults > 0) {
          bot.reply(message,"Top five results: " + query.slice(0,numResults).join(', '));
        }
        else {
          bot.reply(message,"No good results. Ask Ricky.");
        }
      }
      getNutrimatic(query, processQuery);
    })
  })
});

<commit_msg>remove some console.logs<commit_after>/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          ______     ______     ______   __  __     __     ______
          /\  == \   /\  __ \   /\__  _\ /\ \/ /    /\ \   /\__  _\
          \ \  __<   \ \ \/\ \  \/_/\ \/ \ \  _"-.  \ \ \  \/_/\ \/
          \ \_____\  \ \_____\    \ \_\  \ \_\ \_\  \ \_\    \ \_\
           \/_____/   \/_____/     \/_/   \/_/\/_/   \/_/     \/_/

This is a sample Slack bot built with Botkit.

This bot demonstrates many of the core features of Botkit:

* Connect to Slack using the real time API
* Receive messages based on "spoken" patterns
* Reply to messages
* Use the conversation system to ask questions
* Use the built in storage system to store and retrieve information
  for a user.

# RUN THE BOT:

  Get a Bot token from Slack:

    -> http://my.slack.com/services/new/bot

  Run your bot from the command line:

    token=<MY TOKEN> node bot.js

# USE THE BOT:

  Find your bot inside Slack to send it a direct message.

  Say: "Hello"

  The bot will reply "Hello!"

  Say: "who are you?"

  The bot will tell you its name, where it running, and for how long.

  Say: "Call me <nickname>"

  Tell the bot your nickname. Now you are friends.

  Say: "who am I?"

  The bot will tell you your nickname, if it knows one for you.

  Say: "shutdown"

  The bot will ask if you are sure, and then shut itself down.

  Make sure to invite your bot into other channels using /invite @<my bot>!

# EXTEND THE BOT:

  Botkit is has many features for building cool and useful bots!

  Read all about it here:

    -> http://howdy.ai/botkit

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//AVOID HEROKU BINDING ERROR
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.send('it is running\n');
}).listen(process.env.PORT || 5000);
//END AVOIDANCE

var Botkit = require('./lib/Botkit.js')
var os = require('os');
var http = require('follow-redirects').http;
var cheerio = require('cheerio');
var StringDecoder = require('string_decoder').StringDecoder;

function getOneAcross(def,cons, cb){
  var options = {
    host: 'www3.oneacross.com',
    path: '/cgi-bin/search_banner.cgi?c0='+encodeURIComponent(def)+'&p0='+ encodeURIComponent(cons)+'&s=+Go%21+'
  };
  console.log(def);
  console.log(cons);
  var result ='';
  var req = http.get(options, function(res) {
    console.log('STATUS: ' + res.statusCode);
    console.log('HEADERS: ' + JSON.stringify(res.headers));
    // Buffer the body entirely for processing as a whole.
    var bodyChunks = [];
    res.on('data', function(chunk) {
      // You can process streamed parts here...
      bodyChunks.push(chunk);
    });
    res.on('end', function() {
      var body = Buffer.concat(bodyChunks);
      $ = cheerio.load(body);
      var words = [];
      $('tt').each(function(i, elem) {
        // var thisWord = $(this).text();
        var starEmoji = ":star:";
        var stars = 0;
        $(this).parent().siblings().first().children().each(function(i, elem) {
          if ($(this).attr('src')=="/images/smallstarblack.gif"){
            stars++;
          }
        });
        // console.log(thisWord + ' ' + stars);

        words.push(starEmoji.repeat(stars) + $(this).text());
      });
      cb(words);
    })
  });
  req.on('error', function(e) {
    console.log('ERROR: ' + e.message);
    return "fail";
  });

  return result;
}

function getNutrimatic(query, cb){
  var options = {
    host: 'www.nutrimatic.org',
    path: '/?q='+query
  };
  console.log(query);
  var result ='';
  var req = http.get(options, function(res) {
    console.log('STATUS: ' + res.statusCode);
    console.log('HEADERS: ' + JSON.stringify(res.headers));
    //console.log('Body: ' + res.body);
    // Buffer the body entirely for processing as a whole.
    var body ='';
    res.setEncoding('utf8');
    res.on('data', function(chunk) {
      // You can process streamed parts here...
      //var textChunk = decoder.write(chunk);
      body = body.concat(chunk);
      //console.log(chunk);
    });
    res.on('end', function() {
      //console.log(body);
      // var body = Buffer.concat(bodyChunks);
      $ = cheerio.load(body);
      //console.log(body);
      var words = [];
      $('span').each(function(i, elem) {
        words.push($(this).text());
      });
      cb(words);
    })
  });
  req.on('error', function(e) {
    console.log('ERROR: ' + e.message);
    return "fail";
  });

  return result;
}

var controller = Botkit.slackbot({
  debug: false,
});

var bot = controller.spawn(
  {
    token:process.env.token
  }
).startRTM();

controller.hears(['hello','hi'],'direct_message,direct_mention,mention',function(bot,message) {

  bot.api.reactions.add({
    timestamp: message.ts,
    channel: message.channel,
    name: 'robot_face',
  },function(err,res) {
    if (err) {
      bot.botkit.log("Failed to add emoji reaction :(",err);
    }
  });

  controller.storage.users.get(message.user,function(err,user) {
    if (user && user.name) {
      bot.reply(message,"Hello " + user.name+"!!");
    } else {
      bot.reply(message,"Hello.");
    }
  });
})

controller.hears(['call me (.*)'],'direct_message,direct_mention,mention',function(bot,message) {
  var matches = message.text.match(/call me (.*)/i);
  var output = '';
  for (var i = 0; i < matches.length; i++) {
    output = output.concat(i, matches[i]);
  }
  var name = matches[1];
  controller.storage.users.get(message.user,function(err,user) {
    if (!user) {
      user = {
        id: message.user,
      }
    }
    user.name = name;
    controller.storage.users.save(user,function(err,id) {
      bot.reply(message,"Got it. I will call you " + output + " from now on.");
    })
  })
});

controller.hears(['what is my name','who am i'],'direct_message,direct_mention,mention',function(bot,message) {

  controller.storage.users.get(message.user,function(err,user) {
    if (user && user.name) {
      bot.reply(message,"Your name is " + user.name);
    } else {
      bot.reply(message,"I don't know yet!");
    }
  })
});

controller.hears(['shutdown'],'direct_message,direct_mention,mention',function(bot,message) {

  bot.startConversation(message,function(err,convo) {
    convo.ask("Are you sure you want me to shutdown?",[
      {
        pattern: bot.utterances.yes,
        callback: function(response,convo) {
          convo.say("Bye!");
          convo.next();
          setTimeout(function() {
            process.exit();
          },3000);
        }
      },
      {
        pattern: bot.utterances.no,
        default:true,
        callback: function(response,convo) {
          convo.say("*Phew!*");
          convo.next();
        }
      }
    ])
  })
})

controller.hears(['uptime','identify yourself','who are you','what is your name'],'direct_message,direct_mention,mention',function(bot,message) {

  var hostname = os.hostname();
  var uptime = formatUptime(process.uptime());

  bot.reply(message,':robot_face: I am a bot named <@' + bot.identity.name +'>. I have been running for ' + uptime + ' on ' + hostname + ".");

})

function formatUptime(uptime) {
  var unit = 'second';
  if (uptime > 60) {
    uptime = uptime / 60;
    unit = 'minute';
  }
  if (uptime > 60) {
    uptime = uptime / 60;
    unit = 'hour';
  }
  if (uptime != 1) {
    unit = unit +'s';
  }

  uptime = uptime + ' ' + unit;
  return uptime;
}

controller.hears(['hello','hi'],'direct_message,direct_mention,mention',function(bot,message) {

  bot.api.reactions.add({
    timestamp: message.ts,
    channel: message.channel,
    name: 'robot_face',
  },function(err,res) {
    if (err) {
      bot.botkit.log("Failed to add emoji reaction :(",err);
    }
  });

  controller.storage.users.get(message.user,function(err,user) {
    if (user && user.name) {
      bot.reply(message,"Hello " + user.name+"!!");
    } else {
      bot.reply(message,"Hello.");
    }
  });
})

//ONE ACROSS
controller.hears(['!OA (.*) ([a-zA-Z0-9?]*)'],'direct_message,direct_mention,mention,ambient',function(bot,message) {
  var matches = message.text.match(/!OA (.*) ([a-zA-Z0-9?]*)/i);

  var definition = matches[1];
  var constraint = matches[2];

  controller.storage.users.get(message.user,function(err,user) {
    if (!user) {
      user = {
        id: message.user,
      }
    }
    controller.storage.users.save(user,function(err,id) {
      function processWords(words){
        words.pop();
        words.pop();
        bot.reply(message,"Results: " + words.join(', '));
      }
      getOneAcross(definition, constraint, processWords);
    })
  })
});

//NUTRIMATIC
controller.hears(['!NM (.*)'],'direct_message,direct_mention,mention,ambient',function(bot,message) {
  var matches = message.text.match(/!NM (.*)/i);
  var query = matches[1];
  query = query.replace("<","<");
  query = query.replace(">",">");
  //query = query.replace(/ /g,"%20");
  //query = query.replace(/"/g,"%22");
  query = encodeURI(query);
  controller.storage.users.get(message.user,function(err,user) {
    if (!user) {
      user = {
        id: message.user,
      }
    }
    controller.storage.users.save(user,function(err,id) {
      function processQuery(query){
        numResults = 5;
        if (query.length < numResults){
          numResults = query.length;
        }
        if (numResults > 0) {
          bot.reply(message,"Top five results: " + query.slice(0,numResults).join(', '));
        }
        else {
          bot.reply(message,"No good results. Ask Ricky.");
        }
      }
      getNutrimatic(query, processQuery);
    })
  })
});

<|endoftext|>


<commit_before>const Discord = require('discord.js');
const client = new Discord.Client();
const weather = require('weather-js');
//const mysql = require('mysql');
const sql = require("sqlite");

//----------------------------------------------------------------------------------------------------------------------------------

sql.open("./score.sqlite");

//----------------------------------------------------------------------------------------------------------------------------------

client.config = require('./config.json');
client.log = require('./functions/log.js');
client.commands = new Discord.Collection();

//----------------------------------------------------------------------------------------------------------------------------------

//COMANDOS
client.commands.set('ping', require('./commands/ping.js'));
client.commands.set('falar', require('./commands/falar.js'));
client.commands.set('ajuda', require('./commands/ajuda.js'));
client.commands.set('limpar', require('./commands/limpar.js'));
client.commands.set('ban', require('./commands/ban.js'));
client.commands.set('kick', require('./commands/kick.js'));
client.commands.set('unban', require('./commands/unban.js'));
client.commands.set('roll', require('./commands/roll.js'));
client.commands.set('bot', require('./commands/conversaBot.js'));
client.commands.set('morra', require('./commands/conversaMorra.js'));
client.commands.set('soma', require('./commands/calcularSoma.js'));
client.commands.set('sub', require('./commands/calcularSub.js'));
client.commands.set('mult', require('./commands/calcularMult.js'));
client.commands.set('div', require('./commands/calcularDiv.js'));
client.commands.set('fsalvos', require('./commands/canalSalvos.js'));
client.commands.set('fprincipal', require('./commands/canalPrincipal.js'));
client.commands.set('resp', require('./commands/resp.js'));
client.commands.set('playinitiald', require('./commands/radioPlayInitialD.js'));
client.commands.set('playmoe', require('./commands/radioPlayMoe.js'));
client.commands.set('playanimenfo', require('./commands/radioPlayAnimeNfo.js'));
client.commands.set('stop', require('./commands/radioStop.js'));
client.commands.set('userinfo', require('./commands/userinfo.js'));
client.commands.set('serverinfo', require('./commands/serverinfo.js'));
client.commands.set('tempo', require('./commands/tempo.js'));
client.commands.set('afk', require('./commands/joinAway.js'));
client.commands.set('level', require('./commands/levelXp.js'));
client.commands.set('pontos', require('./commands/levelPoints.js'));

//----------------------------------------------------------------------------------------------------------------------------------

//MENSAGEM
client.on('messageReactionAdd', (reaction, user) => require('./events/messageReactionAdd.js')(client, reaction, user));
//----------------------------------------------------------------------------------------------------------------------------------
client.on('message', message => {
  sql.get(`SELECT * FROM scores WHERE userId ="${message.author.id}"`).then(row =>
  { if (!row) { sql.run("INSERT INTO scores (userId, points, level) VALUES (?, ?, ?)", [message.author.id, 1, 0]);
  } else {  let curLevel = Math.floor(0.1 * Math.sqrt(row.points + 1));
    if (curLevel > row.level) { row.level = curLevel;  sql.run(`UPDATE scores SET points = ${row.points + 1}, level = ${row.level} WHERE userId = ${message.author.id}`);  message.reply(`Ding! Parabéns! Você subiu de level. O seu level atual é **${curLevel}**!`);    }
  sql.run(`UPDATE scores SET points = ${row.points + 1} WHERE userId = ${message.author.id}`);  }
  }).catch(() => { console.error;
  sql.run("CREATE TABLE IF NOT EXISTS scores (userId TEXT, points INTEGER, level INTEGER)").then(() => {
  sql.run("INSERT INTO scores (userId, points, level) VALUES (?, ?, ?)", [message.author.id, 1, 0]);   });  });
  require('./events/message.js')(client, message, sql) });
//----------------------------------------------------------------------------------------------------------------------------------

//READY
client.on('ready', () => { var channel = client.channels.get('167715230082662401'); channel.sendMessage("**O BoT está online!**").then(msg => {msg.delete(60000)}); require('./events/ready.js')(client) });

//GUILD
client.on('guildCreate', guild => require('./events/guildCreate.js')(client, guild));
client.on('guildMemberAdd', (member, message, channel) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('Seja bem vindo(a) '+member.user.username+'!').then(msg => {msg.delete(60000)}) } );
client.on('guildMemberRemove', (member, message, channel) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('Adeus '+member.user.username+'!').then(msg => {msg.delete(60000)}) } );
client.on('guildMemberUpdate', (oldMember, newMember) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('O usuário '+oldMember+' **atualizou** os seus dados!').then(msg => {msg.delete(60000)}) } );
client.on('guildUpdate', (guild, oldGuild, newGuild) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('O servidor '+oldGuild+' foi **atualizado**!').then(msg => {msg.delete(60000)}) } );
client.on('guildBanAdd', (guild, user) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('O usuário '+user+' foi **banido**!').then(msg => {msg.delete(60000)}) } );
client.on('guildBanRemove', (guild, user) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('O usuário '+user+' foi **desbanido**!').then(msg => {msg.delete(60000)}) } );

//CANAL
client.on('channelCreate', (channel) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('Uma nova **sala de conversa** foi **criada**!').then(msg => {msg.delete(60000)}) } );
client.on('channelDelete', (channel, guild) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('Uma **sala de conversa** foi **deletada**!').then(msg => {msg.delete(60000)}) } );
client.on('channelPinsUpdate', (channel, time) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('Uma nova mensagem foi **fixada** em '+time+'!').then(msg => {msg.delete(60000)}) } );
client.on('channelUpdate', (channel, oldChannel, newChannel) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('A **sala de conversa** '+oldChannel+' foi atualizada!').then(msg => {msg.delete(60000)}) } );

//----------------------------------------------------------------------------------------------------------------------------------
//-----Nao usado por causa de spam
/*client.on('voiceStateUpdate', (oldMember, newMember) => { let newUserChannel = newMember.voiceChannel; let oldUserChannel = oldMember.voiceChannel;
if(oldUserChannel === undefined && newUserChannel !== undefined) { entra no canal --- CODIGO de msg aqui } else if(newUserChannel === undefined){ sai no canal --- CODIGO de msg aqui }}); */
//----------------------------------------------------------------------------------------------------------------------------------
//-----mysql Heroku connect database
/*var con;
if(process.env.DATABASE_URL) { con = mysql.createConnection(process.env.DATABASE_URL); } */

//client.login(config.token)
client.login(process.env.BOT_TOKEN);<commit_msg><commit_after>const Discord = require('discord.js');
const client = new Discord.Client();
const weather = require('weather-js');
//const mysql = require('mysql');
const sql = require("sqlite");

//----------------------------------------------------------------------------------------------------------------------------------

sql.open("./score.sqlite");

//----------------------------------------------------------------------------------------------------------------------------------

client.config = require('./config.json');
client.log = require('./functions/log.js');
client.commands = new Discord.Collection();

//----------------------------------------------------------------------------------------------------------------------------------

//COMANDOS
client.commands.set('ping', require('./commands/ping.js'));
client.commands.set('falar', require('./commands/falar.js'));
client.commands.set('ajuda', require('./commands/ajuda.js'));
client.commands.set('limpar', require('./commands/limpar.js'));
client.commands.set('ban', require('./commands/ban.js'));
client.commands.set('kick', require('./commands/kick.js'));
client.commands.set('unban', require('./commands/unban.js'));
client.commands.set('roll', require('./commands/roll.js'));
client.commands.set('bot', require('./commands/conversaBot.js'));
client.commands.set('morra', require('./commands/conversaMorra.js'));
client.commands.set('soma', require('./commands/calcularSoma.js'));
client.commands.set('sub', require('./commands/calcularSub.js'));
client.commands.set('mult', require('./commands/calcularMult.js'));
client.commands.set('div', require('./commands/calcularDiv.js'));
client.commands.set('fsalvos', require('./commands/canalSalvos.js'));
client.commands.set('fprincipal', require('./commands/canalPrincipal.js'));
client.commands.set('resp', require('./commands/resp.js'));
client.commands.set('playinitiald', require('./commands/radioPlayInitialD.js'));
client.commands.set('playmoe', require('./commands/radioPlayMoe.js'));
client.commands.set('playanimenfo', require('./commands/radioPlayAnimeNfo.js'));
client.commands.set('stop', require('./commands/radioStop.js'));
client.commands.set('userinfo', require('./commands/userinfo.js'));
client.commands.set('serverinfo', require('./commands/serverinfo.js'));
client.commands.set('tempo', require('./commands/tempo.js'));
client.commands.set('afk', require('./commands/joinAway.js'));
client.commands.set('level', require('./commands/levelXp.js'));
client.commands.set('pontos', require('./commands/levelPoints.js'));

//----------------------------------------------------------------------------------------------------------------------------------

//MENSAGEM
client.on('messageReactionAdd', (reaction, user) => require('./events/messageReactionAdd.js')(client, reaction, user));
//----------------------------------------------------------------------------------------------------------------------------------
client.on('message', message => {
  sql.get(`SELECT * FROM scores WHERE userId ="${message.author.id}"`).then(row =>
  { if (!row) { sql.run("INSERT INTO scores (userId, points, level) VALUES (?, ?, ?)", [message.author.id, 1, 0]);
  } else {  let curLevel = Math.floor(0.1 * Math.sqrt(row.points + 1));
    if (curLevel > row.level) { row.level = curLevel;  sql.run(`UPDATE scores SET points = ${row.points + 1}, level = ${row.level} WHERE userId = ${message.author.id}`);  message.reply(`Ding! Parabéns! Você subiu de level. O seu level atual é **${curLevel}**!`);    }
  sql.run(`UPDATE scores SET points = ${row.points + 1} WHERE userId = ${message.author.id}`);  }
  }).catch(() => { console.error;
  sql.run("CREATE TABLE IF NOT EXISTS scores (userId TEXT, points INTEGER, level INTEGER)").then(() => {
  sql.run("INSERT INTO scores (userId, points, level) VALUES (?, ?, ?)", [message.author.id, 1, 0]);   });  });
  require('./events/message.js')(client, message, sql) });
//----------------------------------------------------------------------------------------------------------------------------------

//READY
client.on('ready', () => { var channel = client.channels.get('167715230082662401'); channel.sendMessage("**O BoT está online!**").then(msg => {msg.delete(60000)}); require('./events/ready.js')(client) });

//GUILD
client.on('guildCreate', guild => require('./events/guildCreate.js')(client, guild));
client.on('guildMemberAdd', (member, message, channel) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('Seja bem vindo(a) '+member.user.username+'!').then(msg => {msg.delete(60000)}) } );
client.on('guildMemberRemove', (member, message, channel) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('Adeus '+member.user.username+'!').then(msg => {msg.delete(60000)}) } );
client.on('guildMemberUpdate', (oldMember, newMember) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('O usuário '+oldMember+' **atualizou** os seus dados!').then(msg => {msg.delete(60000)}) } );
client.on('guildUpdate', (guild, oldGuild, newGuild) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('O servidor '+oldGuild+' foi **atualizado**!').then(msg => {msg.delete(60000)}) } );
client.on('guildBanAdd', (guild, user) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('O usuário '+user+' foi **banido**!').then(msg => {msg.delete(60000)}) } );
client.on('guildBanRemove', (guild, user) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('O usuário '+user+' foi **desbanido**!').then(msg => {msg.delete(60000)}) } );

//EMOJI
client.on('emojiCreate', (emoji) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('Um novo **Emoji** foi adicionado!').then(msg => {msg.delete(60000)}) } );
client.on('emojiDelete', (emoji) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('Um **Emoji** foi deletado!!').then(msg => {msg.delete(60000)}) } );
client.on('emojiUpdate', (emoji, oldEmoji, newEmoji) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('O '+oldEmoji+' foi **atualizado**!').then(msg => {msg.delete(60000)}) } );

//CANAL
client.on('channelCreate', (channel) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('Uma nova **sala de conversa** foi **criada**!').then(msg => {msg.delete(60000)}) } );
client.on('channelDelete', (channel, guild) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('Uma **sala de conversa** foi **deletada**!').then(msg => {msg.delete(60000)}) } );
client.on('channelPinsUpdate', (channel, time) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('Uma nova mensagem foi **fixada** em '+time+'!').then(msg => {msg.delete(60000)}) } );
client.on('channelUpdate', (channel, oldChannel, newChannel) => { var channel = client.channels.get('167715230082662401'); channel.sendMessage('A **sala de conversa** '+oldChannel+' foi atualizada!').then(msg => {msg.delete(60000)}) } );

//----------------------------------------------------------------------------------------------------------------------------------
//-----Nao usado por causa de spam
/*client.on('voiceStateUpdate', (oldMember, newMember) => { let newUserChannel = newMember.voiceChannel; let oldUserChannel = oldMember.voiceChannel;
if(oldUserChannel === undefined && newUserChannel !== undefined) { entra no canal --- CODIGO de msg aqui } else if(newUserChannel === undefined){ sai no canal --- CODIGO de msg aqui }}); */
//----------------------------------------------------------------------------------------------------------------------------------
//-----mysql Heroku connect database
/*var con;
if(process.env.DATABASE_URL) { con = mysql.createConnection(process.env.DATABASE_URL); } */

//client.login(config.token)
client.login(process.env.BOT_TOKEN);<|endoftext|>


<commit_before>// filesystem node
var fs = require('fs');

if (fs.existsSync('./config.json')) {
    var config = require("./config.json");
    var discordKey = config.discordKey;
    var witKey = config.witKey;
    var wolframKey = config.wolframKey;
    var giphyKey = config.giphyKey;
    var youtubeKey = config.youtubeKey;
}
else {
  var discordKey = process.env.discordKey;
  var witKey = process.env.witKey;
  var wolframKey = process.env.wolframKey;
  var giphyKey = process.env.giphyKey;
  var youtubeKey = process.env.youtubeKey;
}

const Discord = require('discord.js');
const client = new Discord.Client();
client.login(discordKey);

var bot = require("discord-music-bot");

var config = require("./config.json");
var discordKey = config.discordKey;
var witKey = config.witKey;
var wolframKey = config.wolframKey;
var giphyKey = config.giphyKey;
var youtubeKey = config.youtubeKey;

bot.setYoutubeKey(youtubeKey);
var serverName = 'The Elder Scrollers';
var textChannelName = "music-talk";
var voiceChannelName = "Skyrim Bard Music";
var aliasesFile = "aliasesMusic";
var botToken = discordKey;

bot.run(serverName, textChannelName, voiceChannelName, aliasesFile, botToken);
<commit_msg>Update to bot<commit_after>// filesystem node
var fs = require('fs');

if (fs.existsSync('./config.json')) {
    var config = require("./config.json");
    var discordKey = config.discordKey;
    var witKey = config.witKey;
    var wolframKey = config.wolframKey;
    var giphyKey = config.giphyKey;
    var youtubeKey = config.youtubeKey;
}
else {
  var discordKey = process.env.discordKey;
  var witKey = process.env.witKey;
  var wolframKey = process.env.wolframKey;
  var giphyKey = process.env.giphyKey;
  var youtubeKey = process.env.youtubeKey;
}

const Discord = require('discord.js');
const client = new Discord.Client();
client.login(discordKey);

var bot = require("discord-music-bot");

// var config = require("./config.json");
var discordKey = config.discordKey;
var witKey = config.witKey;
var wolframKey = config.wolframKey;
var giphyKey = config.giphyKey;
var youtubeKey = config.youtubeKey;

bot.setYoutubeKey(youtubeKey);
var serverName = 'The Elder Scrollers';
var textChannelName = "music-talk";
var voiceChannelName = "Skyrim Bard Music";
var aliasesFile = "aliasesMusic";
var botToken = discordKey;

bot.run(serverName, textChannelName, voiceChannelName, aliasesFile, botToken);
<|endoftext|>


<commit_before>'use strict'

const request = require('request')
const cheerio = require("cheerio")
const async = require("async")
const Bot = require('messenger-bot')

let bot = new Bot({
  token: process.env.FB_PAGE_ACCESS_TOKEN,
  verify: process.env.FB_PAGE_VERIFY_TOKEN,
  //app_secret: 'APP_SECRET'
})

let _todayZodiac = {};

bot.on('error', (err) => {
  console.log(err.message)
})

let menulv1 = {
  "template_type": "generic",
  "elements": [{
    "title": "First card",
    "subtitle": "Element #1 of an hscroll",
    "image_url": "http://messengerdemo.parseapp.com/img/rift.png",
    "buttons": [{
        "type": "web_url",
        "url": "https://www.messenger.com",
        "title": "web url"
    }, {
        "type": "postback",
        "title": "Button",
        "payload": "button",
    }, {
        "type": "postback",
        "title": "Video",
        "payload": "video",
    }]
  }, {
    "title": "Second card",
    "subtitle": "Element #2 of an hscroll",
    "image_url": "http://messengerdemo.parseapp.com/img/rift.png",
    "buttons": [{
        "type": "postback",
        "title": "Audio",
        "payload": "audio",
    }, {
        "type": "postback",
        "title": "Recipe",
        "payload": "recipe",
    }, {
        "type": "postback",
        "title": "Quick",
        "payload": "quick",
    }]
  }, {
    "title": "Third card",
    "subtitle": "Element #3 of an hscroll",
    "image_url": "http://messengerdemo.parseapp.com/img/rift.png",
    "buttons": [{
        "type": "postback",
        "title": "Image",
        "payload": "image",
    }]
  }]
}

let button = {
  "attachment":{
    "type":"template",
    "payload":{
      "template_type":"button",
      "text":"What do you want to do next?",
      "buttons":[
        {
          "type":"web_url",
          "url":"https://petersapparel.parseapp.com",
          "title":"Show Website"
        },
        {
          "type":"postback",
          "title":"Start Chatting",
          "payload":"USER_DEFINED_PAYLOAD"
        }
      ]
    }
  }
}

let video = {
  "attachment":{
    "type":"video",
    "payload":{
      "url":"https://petersapparel.com/bin/clip.mp4"
    }
  }
}

let image = {
  "attachment":{
    "type":"image",
    "payload":{
      "url":"http://s3.favim.com/orig/42/-animal-animals-cute-dog-Favim.com-361124.jpg"
    }
  }
}

let audio = {
  "attachment":{
    "type":"audio",
    "payload":{
      "url":"https://petersapparel.com/bin/clip.mp3"
    }
  }
}

let recipe = {
  "attachment":{
    "type":"template",
    "payload":{
      "template_type":"receipt",
      "recipient_name":"Stephane Crozatier",
      "order_number":"12345678902",
      "currency":"USD",
      "payment_method":"Visa 2345",
      "order_url":"http://petersapparel.parseapp.com/order?order_id=123456",
      "timestamp":"1428444852",
      "elements":[
        {
          "title":"Classic White T-Shirt",
          "subtitle":"100% Soft and Luxurious Cotton",
          "quantity":2,
          "price":50,
          "currency":"USD",
          "image_url":"http://petersapparel.parseapp.com/img/whiteshirt.png"
        },
        {
          "title":"Classic Gray T-Shirt",
          "subtitle":"100% Soft and Luxurious Cotton",
          "quantity":1,
          "price":25,
          "currency":"USD",
          "image_url":"http://petersapparel.parseapp.com/img/grayshirt.png"
        }
      ],
      "address":{
        "street_1":"1 Hacker Way",
        "street_2":"",
        "city":"Menlo Park",
        "postal_code":"94025",
        "state":"CA",
        "country":"US"
      },
      "summary":{
        "subtotal":75.00,
        "shipping_cost":4.95,
        "total_tax":6.19,
        "total_cost":56.14
      },
      "adjustments":[
        {
          "name":"New Customer Discount",
          "amount":20
        },
        {
          "name":"$10 Off Coupon",
          "amount":10
        }
      ]
    }
  }
}

let quickReliesMsg = {
  "text":"Pick a color:",
  "quick_replies":[
    {
      "content_type":"text",
      "title":"Red",
      "payload":"DEVELOPER_DEFINED_PAYLOAD_FOR_PICKING_RED"
    },
    {
      "content_type":"text",
      "title":"Green",
      "payload":"DEVELOPER_DEFINED_PAYLOAD_FOR_PICKING_GREEN"
    }
  ]
}

let zodiacs = {
  "template_type": "generic",
  "elements": [{
    "title": "Bach Duong",
    "subtitle": "Element #1 of an hscroll",
    "image_url": "http://ngaydep.com/templates/ngaydep/images/cung-bach-duong-thumb.jpg",
    "buttons": [{
      "type": "postback",
      "title": "Button",
      "payload": "button.zodiac.bach-duong",
    }]
  }, {
    "title": "Kim Nguu",
    "subtitle": "Element #1 of an hscroll",
    "image_url": "http://ngaydep.com/templates/ngaydep/images/cung-kim-nguu-thumb.jpg",
    "buttons": [{
        "type": "postback",
        "title": "Button",
        "payload": "button.zodiac.kim-nguu",
    }]
  }, {
    "title": "Song tu",
    "subtitle": "Element #1 of an hscroll",
    "image_url": "http://ngaydep.com/templates/ngaydep/images/cung-song-tu-thumb.jpg",
    "buttons": [{
        "type": "postback",
        "title": "Button",
        "payload": "button.zodiac.song-tu",
    }]
  }, {
    "title": "Xu nu",
    "subtitle": "Element #1 of an hscroll",
    "image_url": "http://ngaydep.com/templates/ngaydep/images/cung-xu-nu-thumb.jpg",
    "buttons": [{
        "type": "postback",
        "title": "Xu nu",
        "payload": "button.zodiac.xu-nu"
    }]
  }]
}

bot.on('message', (payload, reply) => {
  let text = payload.message.text
  let senderId = payload.sender.id

  console.log(`Received ${senderId}: ${text}`)

  if (text === 'Menu' || text === 'menu') {
    reply({
      attachment: {
        type: 'template',
        payload: menulv1
      }
    }, (err) => {
      if (err) return console.log("reply error" + err.message)
      console.log(`Echoed back to ${senderId}: ${text}`)
    })
  } else if(text==='Zodiac' || text==='zodiac' || text==='Tuvi' || text==='tuvi') {
    reply({
      attachment: {
        type: 'template',
        payload: zodiacs
      }
    }, (err) => {
      if (err) return console.log("reply error" + err.message)
      console.log(`Echoed back to ${senderId}: ${text}`)
    })
  } else {
    bot.getProfile(senderId, (err, profile) => {
      if (err) return console.log("get profile" + err.message)

      reply({ text }, (err) => {
        if (err) return console.log("reply error" + err.message)

        console.log(`Echoed back to ${profile.first_name} ${profile.last_name}: ${text}`)
      })
    })
  }
})

bot.on('postback', (payload, reply) => {
  console.log(`Received postback. payload ${JSON.stringify(payload)}`)

  let senderId = payload.sender.id
  let text = payload.postback.payload

  let message = {}

  let isZodiac = /^button.zodiac.*/.test(text);
  if (isZodiac) {
    let match = text.match(/^button.zodiac.(.*)/)
    let zodiac = match[1] || "cu-giai";

    getTodayZodiac(zodiac, function(err, result) {
      if (err) return console.log("get profile" + err.message)

      // console.log('detail:', result);

      // split result to array
      result = result.match(/.{1,320}/g);

      let series = [];

      for (var i = 0; i < result.length - 1; i++) {
        series.push(function(done) {
          reply({ text: `${result[i]}` }, (err, info) => {
            if (err) return done(err)
            done(null);
          })
        })
      }

      async.series(series, function(err) {
        if (err) return console.log("send message error:" + err.message)

        console.log(`postback payload: ${text}`)
        return;
      });
    });
  } else {
    switch(text) {
      case 'button':
        message = button
        break;
      case 'video':
        message = video
        break;
      case 'image':
        message = image
        break;
      case 'audio':
        message = audio
        break;
      case 'recipe':
        message = recipe
        break;
      case 'quick':
        message = quickReliesMsg
        break;
      default:
        message = { text: 'hey!' }
        break;
    }

    reply(message, (err, info) => {
      if (err) return console.log("reply error" + err.message)

      console.log(`postback payload: ${text}`)
    })
  }
})

function getTodayZodiac(zodiac, callback) {

  let today = new Date();
  let key = `${today.getFullYear()}-${today.getMonth() + 1}-${today.getDate()}-${zodiac}`

  if (_todayZodiac[key]) {
    console.log("found today zodiac data with key:", key)
    return callback(null, _todayZodiac[key])
  }

  //Lets try to make a HTTP GET request to modulus.io's website.
  //Lets configure and request
  request({
    url: 'http://ngaydep.com/tu-vi-hang-ngay.html', //URL to hit
    //qs: {from: 'blog example', time: +new Date()}, //Query string data
    method: 'POST',
    //Lets post the following key/values as form
    form: {
      d: today.getDate(),
      m: today.getMonth() + 1,
      y: today.getFullYear(),
      alias: `${zodiac}`
    }
  }, function (error, response, body) {
    if (error) return callback(error);

    //Check for right status code
    if(response.statusCode !== 200){
      console.log('Invalid Status Code Returned:', response.statusCode);
      return callback(new Error(`Invalid Status Code Returned: ${response.statusCode}`))
    }

    //All is good. Print the body
    // console.log(body); // Show the HTML for the Modulus homepage.

    let $ = cheerio.load(body);
    let detail = $('.chitiet_hd p').text()
    // console.log('detail:', detail);

    // set today zodiac
    _todayZodiac[key] = detail

    callback(null, detail);
  });
}

module.exports = bot<commit_msg>fix bug4<commit_after>'use strict'

const request = require('request')
const cheerio = require("cheerio")
const async = require("async")
const Bot = require('messenger-bot')

let bot = new Bot({
  token: process.env.FB_PAGE_ACCESS_TOKEN,
  verify: process.env.FB_PAGE_VERIFY_TOKEN,
  //app_secret: 'APP_SECRET'
})

let _todayZodiac = {};

bot.on('error', (err) => {
  console.log(err.message)
})

let menulv1 = {
  "template_type": "generic",
  "elements": [{
    "title": "First card",
    "subtitle": "Element #1 of an hscroll",
    "image_url": "http://messengerdemo.parseapp.com/img/rift.png",
    "buttons": [{
        "type": "web_url",
        "url": "https://www.messenger.com",
        "title": "web url"
    }, {
        "type": "postback",
        "title": "Button",
        "payload": "button",
    }, {
        "type": "postback",
        "title": "Video",
        "payload": "video",
    }]
  }, {
    "title": "Second card",
    "subtitle": "Element #2 of an hscroll",
    "image_url": "http://messengerdemo.parseapp.com/img/rift.png",
    "buttons": [{
        "type": "postback",
        "title": "Audio",
        "payload": "audio",
    }, {
        "type": "postback",
        "title": "Recipe",
        "payload": "recipe",
    }, {
        "type": "postback",
        "title": "Quick",
        "payload": "quick",
    }]
  }, {
    "title": "Third card",
    "subtitle": "Element #3 of an hscroll",
    "image_url": "http://messengerdemo.parseapp.com/img/rift.png",
    "buttons": [{
        "type": "postback",
        "title": "Image",
        "payload": "image",
    }]
  }]
}

let button = {
  "attachment":{
    "type":"template",
    "payload":{
      "template_type":"button",
      "text":"What do you want to do next?",
      "buttons":[
        {
          "type":"web_url",
          "url":"https://petersapparel.parseapp.com",
          "title":"Show Website"
        },
        {
          "type":"postback",
          "title":"Start Chatting",
          "payload":"USER_DEFINED_PAYLOAD"
        }
      ]
    }
  }
}

let video = {
  "attachment":{
    "type":"video",
    "payload":{
      "url":"https://petersapparel.com/bin/clip.mp4"
    }
  }
}

let image = {
  "attachment":{
    "type":"image",
    "payload":{
      "url":"http://s3.favim.com/orig/42/-animal-animals-cute-dog-Favim.com-361124.jpg"
    }
  }
}

let audio = {
  "attachment":{
    "type":"audio",
    "payload":{
      "url":"https://petersapparel.com/bin/clip.mp3"
    }
  }
}

let recipe = {
  "attachment":{
    "type":"template",
    "payload":{
      "template_type":"receipt",
      "recipient_name":"Stephane Crozatier",
      "order_number":"12345678902",
      "currency":"USD",
      "payment_method":"Visa 2345",
      "order_url":"http://petersapparel.parseapp.com/order?order_id=123456",
      "timestamp":"1428444852",
      "elements":[
        {
          "title":"Classic White T-Shirt",
          "subtitle":"100% Soft and Luxurious Cotton",
          "quantity":2,
          "price":50,
          "currency":"USD",
          "image_url":"http://petersapparel.parseapp.com/img/whiteshirt.png"
        },
        {
          "title":"Classic Gray T-Shirt",
          "subtitle":"100% Soft and Luxurious Cotton",
          "quantity":1,
          "price":25,
          "currency":"USD",
          "image_url":"http://petersapparel.parseapp.com/img/grayshirt.png"
        }
      ],
      "address":{
        "street_1":"1 Hacker Way",
        "street_2":"",
        "city":"Menlo Park",
        "postal_code":"94025",
        "state":"CA",
        "country":"US"
      },
      "summary":{
        "subtotal":75.00,
        "shipping_cost":4.95,
        "total_tax":6.19,
        "total_cost":56.14
      },
      "adjustments":[
        {
          "name":"New Customer Discount",
          "amount":20
        },
        {
          "name":"$10 Off Coupon",
          "amount":10
        }
      ]
    }
  }
}

let quickReliesMsg = {
  "text":"Pick a color:",
  "quick_replies":[
    {
      "content_type":"text",
      "title":"Red",
      "payload":"DEVELOPER_DEFINED_PAYLOAD_FOR_PICKING_RED"
    },
    {
      "content_type":"text",
      "title":"Green",
      "payload":"DEVELOPER_DEFINED_PAYLOAD_FOR_PICKING_GREEN"
    }
  ]
}

let zodiacs = {
  "template_type": "generic",
  "elements": [{
    "title": "Bach Duong",
    "subtitle": "Element #1 of an hscroll",
    "image_url": "http://ngaydep.com/templates/ngaydep/images/cung-bach-duong-thumb.jpg",
    "buttons": [{
      "type": "postback",
      "title": "Button",
      "payload": "button.zodiac.bach-duong",
    }]
  }, {
    "title": "Kim Nguu",
    "subtitle": "Element #1 of an hscroll",
    "image_url": "http://ngaydep.com/templates/ngaydep/images/cung-kim-nguu-thumb.jpg",
    "buttons": [{
        "type": "postback",
        "title": "Button",
        "payload": "button.zodiac.kim-nguu",
    }]
  }, {
    "title": "Song tu",
    "subtitle": "Element #1 of an hscroll",
    "image_url": "http://ngaydep.com/templates/ngaydep/images/cung-song-tu-thumb.jpg",
    "buttons": [{
        "type": "postback",
        "title": "Button",
        "payload": "button.zodiac.song-tu",
    }]
  }, {
    "title": "Xu nu",
    "subtitle": "Element #1 of an hscroll",
    "image_url": "http://ngaydep.com/templates/ngaydep/images/cung-xu-nu-thumb.jpg",
    "buttons": [{
        "type": "postback",
        "title": "Xu nu",
        "payload": "button.zodiac.xu-nu"
    }]
  }]
}

bot.on('message', (payload, reply) => {
  let text = payload.message.text
  let senderId = payload.sender.id

  console.log(`Received ${senderId}: ${text}`)

  if (text === 'Menu' || text === 'menu') {
    reply({
      attachment: {
        type: 'template',
        payload: menulv1
      }
    }, (err) => {
      if (err) return console.log("reply error" + err.message)
      console.log(`Echoed back to ${senderId}: ${text}`)
    })
  } else if(text==='Zodiac' || text==='zodiac' || text==='Tuvi' || text==='tuvi') {
    reply({
      attachment: {
        type: 'template',
        payload: zodiacs
      }
    }, (err) => {
      if (err) return console.log("reply error" + err.message)
      console.log(`Echoed back to ${senderId}: ${text}`)
    })
  } else {
    bot.getProfile(senderId, (err, profile) => {
      if (err) return console.log("get profile" + err.message)

      reply({ text }, (err) => {
        if (err) return console.log("reply error" + err.message)

        console.log(`Echoed back to ${profile.first_name} ${profile.last_name}: ${text}`)
      })
    })
  }
})

bot.on('postback', (payload, reply) => {
  console.log(`Received postback. payload ${JSON.stringify(payload)}`)

  let senderId = payload.sender.id
  let text = payload.postback.payload

  let message = {}

  let isZodiac = /^button.zodiac.*/.test(text);
  if (isZodiac) {
    let match = text.match(/^button.zodiac.(.*)/)
    let zodiac = match[1] || "cu-giai";

    getTodayZodiac(zodiac, function(err, result) {
      if (err) return console.log("get profile" + err.message)

      // console.log('detail:', result);

      // split result to array
      result = result.match(/.{1,320}/g);

      let series = [];

      for (var i = 0; i < result.length - 1; i++) {
        series.push(function(done) {
          reply({ text: `${result[i]}` }, (err, info) => {
            if (err) return done(err)
            console.log(result[i]);
            done(null);
          })
        })
      }

      async.series(series, function(err) {
        if (err) return console.log("send message error:" + err.message)

        console.log(`postback payload: ${text}`)
        return;
      });
    });
  } else {
    switch(text) {
      case 'button':
        message = button
        break;
      case 'video':
        message = video
        break;
      case 'image':
        message = image
        break;
      case 'audio':
        message = audio
        break;
      case 'recipe':
        message = recipe
        break;
      case 'quick':
        message = quickReliesMsg
        break;
      default:
        message = { text: 'hey!' }
        break;
    }

    reply(message, (err, info) => {
      if (err) return console.log("reply error" + err.message)

      console.log(`postback payload: ${text}`)
    })
  }
})

function getTodayZodiac(zodiac, callback) {

  let today = new Date();
  let key = `${today.getFullYear()}-${today.getMonth() + 1}-${today.getDate()}-${zodiac}`

  if (_todayZodiac[key]) {
    console.log("found today zodiac data with key:", key)
    return callback(null, _todayZodiac[key])
  }

  //Lets try to make a HTTP GET request to modulus.io's website.
  //Lets configure and request
  request({
    url: 'http://ngaydep.com/tu-vi-hang-ngay.html', //URL to hit
    //qs: {from: 'blog example', time: +new Date()}, //Query string data
    method: 'POST',
    //Lets post the following key/values as form
    form: {
      d: today.getDate(),
      m: today.getMonth() + 1,
      y: today.getFullYear(),
      alias: `${zodiac}`
    }
  }, function (error, response, body) {
    if (error) return callback(error);

    //Check for right status code
    if(response.statusCode !== 200){
      console.log('Invalid Status Code Returned:', response.statusCode);
      return callback(new Error(`Invalid Status Code Returned: ${response.statusCode}`))
    }

    //All is good. Print the body
    // console.log(body); // Show the HTML for the Modulus homepage.

    let $ = cheerio.load(body);
    let detail = $('.chitiet_hd p').text()
    // console.log('detail:', detail);

    // set today zodiac
    _todayZodiac[key] = detail

    callback(null, detail);
  });
}

module.exports = bot<|endoftext|>


<commit_before>'use strict';

// Weather Example
// See https://wit.ai/sungkim/weather/stories and https://wit.ai/docs/quickstart
const Wit = require('node-wit').Wit;
const FB = require('./facebook.js');
const tokens = require('./tokens.js');

const firstEntityValue = (entities, entity) => {
  const val = entities && entities[entity] &&
    Array.isArray(entities[entity]) &&
    entities[entity].length > 0 &&
    entities[entity][0].value;
  if (!val) {
    return null;
  }
  return typeof val === 'object' ? val.value : val;
};

// Bot actions
const actions = {
  say(sessionId, context, message, callback) {
    console.log(message);

    // Bot testing mode, run callback() and return
    if (require.main === module) {
      callback();
      return;
    }

    // Our bot has something to say!
    // Let's retrieve the Facebook user whose session belongs to from context
    // TODO: need to get Facebook user name
    const id = context.FB_ID;
    if (id) {
      // Yay, we found our recipient!
      // Let's forward our bot response to her.
      FB.message(id, message, (err, data) => {
        if (err) {
          console.log(
            'Oops! An error occurred while forwarding the response to',
            id,
            ':',
            err
          );
        } else {
          console.log('Sending:', data);
        }

        // Let's give the wheel back to our bot
        callback();
      });
    } else {
      console.log('Oops! Couldn\'t find user in context:', context);
      // Giving the wheel back to our bot
      callback();
    }
  },
  merge(sessionId, context, entities, message, callback) {
    // Retrieve the location entity and store it into a context field
    const loc = firstEntityValue(entities, 'location');
    if (loc) {
      context.loc = loc; // store it in context
    }

    callback(context);
  },

  error(sessionId, context, error) {
    console.log(error.message);
  },

  // fetch-weather bot executes
  ['fetch-weather'](sessionId, context, cb) {
    // Here should go the api call, e.g.:
    // context.forecast = apiCall(context.loc)
    context.forecast = 'sunny';
    cb(context);
  }
};

const getWit = () => {
  return new Wit(tokens.WIT_TOKEN, actions);
};

exports.getWit = getWit;

// bot testing mode
// http://stackoverflow.com/questions/6398196
if (require.main === module) {
  console.log('Bot testing mode.');
  const client = getWit();
  client.interactive();
}
<commit_msg>tokens => token<commit_after>'use strict';

// Weather Example
// See https://wit.ai/sungkim/weather/stories and https://wit.ai/docs/quickstart
const Wit = require('node-wit').Wit;
const FB = require('./facebook.js');
const tokens = require('./token.js');

const firstEntityValue = (entities, entity) => {
  const val = entities && entities[entity] &&
    Array.isArray(entities[entity]) &&
    entities[entity].length > 0 &&
    entities[entity][0].value;
  if (!val) {
    return null;
  }
  return typeof val === 'object' ? val.value : val;
};

// Bot actions
const actions = {
  say(sessionId, context, message, callback) {
    console.log(message);

    // Bot testing mode, run callback() and return
    if (require.main === module) {
      callback();
      return;
    }

    // Our bot has something to say!
    // Let's retrieve the Facebook user whose session belongs to from context
    // TODO: need to get Facebook user name
    const id = context.FB_ID;
    if (id) {
      // Yay, we found our recipient!
      // Let's forward our bot response to her.
      FB.message(id, message, (err, data) => {
        if (err) {
          console.log(
            'Oops! An error occurred while forwarding the response to',
            id,
            ':',
            err
          );
        } else {
          console.log('Sending:', data);
        }

        // Let's give the wheel back to our bot
        callback();
      });
    } else {
      console.log('Oops! Couldn\'t find user in context:', context);
      // Giving the wheel back to our bot
      callback();
    }
  },
  merge(sessionId, context, entities, message, callback) {
    // Retrieve the location entity and store it into a context field
    const loc = firstEntityValue(entities, 'location');
    if (loc) {
      context.loc = loc; // store it in context
    }

    callback(context);
  },

  error(sessionId, context, error) {
    console.log(error.message);
  },

  // fetch-weather bot executes
  ['fetch-weather'](sessionId, context, cb) {
    // Here should go the api call, e.g.:
    // context.forecast = apiCall(context.loc)
    context.forecast = 'sunny';
    cb(context);
  }
};

const getWit = () => {
  return new Wit(tokens.WIT_TOKEN, actions);
};

exports.getWit = getWit;

// bot testing mode
// http://stackoverflow.com/questions/6398196
if (require.main === module) {
  console.log('Bot testing mode.');
  const client = getWit();
  client.interactive();
}
<|endoftext|>