<commit_before>var querystring = require('querystring'),
    http = require('follow-redirects').http,
    fs = require('fs'),
    p = require('path'),
    url = require('url');

var Modem = function(opts) {
  this.socketPath = opts.socketPath;
  this.host = opts.host;
  this.port = opts.port;
};

Modem.prototype.dial = function(options, callback) {
  var opts, address, data;
  var self = this;

  if (options.options) {
    opts = options.options;
  }

  if(this.host) {
    address = url.resolve(this.host + ':' + this.port, options.path);
  } else {
    address = options.path;
  }

  if(options.path.indexOf('?') !== -1) {
    if (opts && Object.keys(opts).length > 0) {
      address += querystring.stringify(opts);
    } else {
      address = address.substring(0, address.length - 1);
    }
  }

  var optionsf = {
    path: address,
    method: options.method
  };

  optionsf.headers = {};
  if(options.file) {
    data = fs.readFileSync(p.resolve(options.file));
    optionsf.headers['Content-Type'] = 'application/tar';
  } else if(opts && options.method === 'POST') {
    data = JSON.stringify(opts);
    optionsf.headers['Content-Type'] = 'application/json';
  }

  if(data) {
    optionsf.headers['Content-Length'] = data.length;
  }

  if(this.socketPath) {
    optionsf.socketPath = this.socketPath;
  } else {
    optionsf.hostname = url.parse(address).hostname;
    optionsf.port = url.parse(address).port;
  }

  //console.log(optionsf);

  var req = http.request(optionsf, function() {});

  req.on('response', function(res) {
    if (options.isStream) {
      res.setEncoding('utf8');
      self.buildPayload(null, options.isStream, options.statusCodes, res, null, callback);
    } else {
      var chunks = '';
      res.on('data', function(chunk) {
        chunks += chunk;
      });

      res.on('end', function() {
        var json;
        try {
          json = JSON.parse(chunks);
        } catch(e) {
          json = chunks.split(/\n/);
        }
        self.buildPayload(null, options.isStream, options.statusCodes, res, json, callback);
      });
    }
  });

  req.on('error', function(error) {
    self.buildPayload(error, options.isStream, options.statusCodes, {}, null, callback);
  });

  if(data) {
    req.write(data);
  }
  req.end();
};

Modem.prototype.buildPayload = function(err, isStream, statusCodes, res, json, cb) {
  if (err) cb(err, null);

  if (typeof json === 'string' && !json.isJson()) {
    json = '{"msg": "' + json.replace(/[^a-zA-Z ]/g, "") + '"}';
  } else if (typeof json === 'string') {
    json = JSON.parse(json);
  }

  //console.log(json);

  if (statusCodes[res.statusCode] !== true) {
    var msg = 'HTTP response code is ' + res.statusCode + ' which indicates an error: ' + statusCodes[res.statusCode];
    cb(msg, json);
  } else {
    if (isStream) {
      cb(null, res);
    } else {
      cb(null, json);
    }
  }
};

module.exports = Modem;
<commit_msg>multiple cb calls on docker daemon errors<commit_after>var querystring = require('querystring'),
    http = require('follow-redirects').http,
    fs = require('fs'),
    p = require('path'),
    url = require('url');

var Modem = function(opts) {
  this.socketPath = opts.socketPath;
  this.host = opts.host;
  this.port = opts.port;
};

Modem.prototype.dial = function(options, callback) {
  var opts, address, data;
  var self = this;

  if (options.options) {
    opts = options.options;
  }

  if(this.host) {
    address = url.resolve(this.host + ':' + this.port, options.path);
  } else {
    address = options.path;
  }

  if(options.path.indexOf('?') !== -1) {
    if (opts && Object.keys(opts).length > 0) {
      address += querystring.stringify(opts);
    } else {
      address = address.substring(0, address.length - 1);
    }
  }

  var optionsf = {
    path: address,
    method: options.method
  };

  optionsf.headers = {};
  if(options.file) {
    data = fs.readFileSync(p.resolve(options.file));
    optionsf.headers['Content-Type'] = 'application/tar';
  } else if(opts && options.method === 'POST') {
    data = JSON.stringify(opts);
    optionsf.headers['Content-Type'] = 'application/json';
  }

  if(data) {
    optionsf.headers['Content-Length'] = data.length;
  }

  if(this.socketPath) {
    optionsf.socketPath = this.socketPath;
  } else {
    optionsf.hostname = url.parse(address).hostname;
    optionsf.port = url.parse(address).port;
  }

  //console.log(optionsf);

  var req = http.request(optionsf, function() {});

  req.on('response', function(res) {
    if (options.isStream) {
      res.setEncoding('utf8');
      self.buildPayload(null, options.isStream, options.statusCodes, res, null, callback);
    } else {
      var chunks = '';
      res.on('data', function(chunk) {
        chunks += chunk;
      });

      res.on('end', function() {
        var json;
        try {
          json = JSON.parse(chunks);
        } catch(e) {
          json = chunks.split(/\n/);
        }
        self.buildPayload(null, options.isStream, options.statusCodes, res, json, callback);
      });
    }
  });

  req.on('error', function(error) {
    self.buildPayload(error, options.isStream, options.statusCodes, {}, null, callback);
  });

  if(data) {
    req.write(data);
  }
  req.end();
};

Modem.prototype.buildPayload = function(err, isStream, statusCodes, res, json, cb) {
  if (err) {
    cb(err, null);
  } else {
    if (typeof json === 'string' && !json.isJson()) {
      json = '{"msg": "' + json.replace(/[^a-zA-Z ]/g, "") + '"}';
    } else if (typeof json === 'string') {
      json = JSON.parse(json);
    }

    //console.log(json);

    if (statusCodes[res.statusCode] !== true) {
      var msg = 'HTTP response code is ' + res.statusCode + ' which indicates an error: ' + statusCodes[res.statusCode];
      cb(msg, json);
    } else {
      if (isStream) {
        cb(null, res);
      } else {
        cb(null, json);
      }
    }
  }
};

module.exports = Modem;
<|endoftext|>


<commit_before>const gulp = require('gulp');
const babelify = require('babelify');
const browserify = require('browserify');
const watchify = require('watchify');
const vinylSourceStream = require('vinyl-source-stream');
const vinylBuffer = require('vinyl-buffer');
const stringify = require('stringify');
const del = require('del');
const assign = require('lodash.assign');
const argv = require('yargs').argv;
const $ = require('gulp-load-plugins')();

const src = {
  scripts: {
    all: './src/**/*.js',
    zazu: './src/index.js',
    main: './src/main.js'
  },
  scss: {
    all: './src/**/*.scss'
  },
  css: {
    hotkey: './node_modules/angular-hotkeys/build/hotkeys.min.css'
  },
  html: {
    all: './src/**/!(index).html',
    index: './src/index.html'
  },
  package: './package.json',
  fonts: [
    './node_modules/source-code-pro/WOFF/OTF/SourceCodePro-Regular.otf.woff',
    './node_modules/source-code-pro/WOFF2/OTF/SourceCodePro-Regular.otf.woff2'
  ]
};

const dist = './dist/';

const out = {
  folder: dist,
  scripts: {
    file: 'zazu.min.js'
  },
  scss: {
    file: 'zazu.min.css'
  }
};

const customOptions = {
  entries: src.scripts.zazu,
  debug: true
};
const options = assign({}, watchify.args, customOptions);
const sources = watchify(browserify(options));

sources.transform(babelify);
sources.transform(stringify, {
  appliesTo: {
    includeExtensions: ['.html']
  },
  minify: true
});

gulp.task('scripts', bundle);
sources.on('update', bundle);
sources.on('log', $.util.log);

function bundle () {
  return sources.bundle()
    .on('error', $.util.log.bind($.util, 'Browserify Error'))
    .pipe(vinylSourceStream(out.scripts.file))
    .pipe(vinylBuffer())
    .pipe(gulp.dest(out.folder));
}

gulp.task('scripts:prod', () => {
  return browserify(src.scripts.zazu)
    .transform(babelify)
    .transform(stringify, {
      appliesTo: {
        includeExtensions: ['.html']
      },
      minify: true
    })
    .bundle()
    .pipe(vinylSourceStream(out.scripts.file))
    .pipe(vinylBuffer())
    .pipe($.ngAnnotate())
    .pipe($.uglify())
    .pipe(gulp.dest(out.folder));
});

gulp.task('sass', () => {
  return gulp.src(src.scss.all)
    .pipe($.sass().on('error', $.sass.logError))
    .pipe($.rename(out.scss.file))
    .pipe(gulp.dest(out.folder));
});

gulp.task('clean', () => {
  return del([dist + '**/*']);
});

gulp.task('config', () => {
  gulp.src('zazu.config.json')
    .pipe($.ngConfig('zazu.config', {
      environment: argv.env,
      wrap: 'export default <%= module %>'
    }))
    .pipe(gulp.dest('./src'))
});

gulp.task('watch', () => {
  gulp.watch(src.scripts.all, ['scripts']);
  gulp.watch(src.html.all, ['scripts']);
  gulp.watch(src.scss.all, ['sass']);
});

gulp.task('default', [
  'config',
  'scripts',
  'sass',
  'watch'
]);

gulp.task('package', [
  'config',
  'clean',
  'scripts:prod',
  'sass'
]);
<commit_msg>Removed unnecessary references to files<commit_after>const gulp = require('gulp');
const babelify = require('babelify');
const browserify = require('browserify');
const watchify = require('watchify');
const vinylSourceStream = require('vinyl-source-stream');
const vinylBuffer = require('vinyl-buffer');
const stringify = require('stringify');
const del = require('del');
const assign = require('lodash.assign');
const argv = require('yargs').argv;
const $ = require('gulp-load-plugins')();

const src = {
  scripts: {
    all: './src/**/*.js',
    index: './src/index.js'
  },
  scss: {
    all: './src/**/*.scss'
  },
  html: {
    all: './src/**/!(index).html'
  }
};

const dist = './dist/';

const out = {
  folder: dist,
  scripts: {
    file: 'zazu.min.js'
  },
  scss: {
    file: 'zazu.min.css'
  }
};

const customOptions = {
  entries: src.scripts.index,
  debug: true
};
const options = assign({}, watchify.args, customOptions);
const sources = watchify(browserify(options));

sources.transform(babelify);
sources.transform(stringify, {
  appliesTo: {
    includeExtensions: ['.html']
  },
  minify: true
});

gulp.task('scripts', bundle);
sources.on('update', bundle);
sources.on('log', $.util.log);

function bundle () {
  return sources.bundle()
    .on('error', $.util.log.bind($.util, 'Browserify Error'))
    .pipe(vinylSourceStream(out.scripts.file))
    .pipe(vinylBuffer())
    .pipe(gulp.dest(out.folder));
}

gulp.task('scripts:prod', () => {
  return browserify(src.scripts.index)
    .transform(babelify)
    .transform(stringify, {
      appliesTo: {
        includeExtensions: ['.html']
      },
      minify: true
    })
    .bundle()
    .pipe(vinylSourceStream(out.scripts.file))
    .pipe(vinylBuffer())
    .pipe($.ngAnnotate())
    .pipe($.uglify())
    .pipe(gulp.dest(out.folder));
});

gulp.task('sass', () => {
  return gulp.src(src.scss.all)
    .pipe($.sass().on('error', $.sass.logError))
    .pipe($.rename(out.scss.file))
    .pipe(gulp.dest(out.folder));
});

gulp.task('clean', () => {
  return del([dist + '**/*']);
});

gulp.task('config', () => {
  gulp.src('zazu.config.json')
    .pipe($.ngConfig('zazu.config', {
      environment: argv.env,
      wrap: 'export default <%= module %>'
    }))
    .pipe(gulp.dest('./src'))
});

gulp.task('watch', () => {
  gulp.watch(src.scripts.all, ['scripts']);
  gulp.watch(src.html.all, ['scripts']);
  gulp.watch(src.scss.all, ['sass']);
});

gulp.task('default', [
  'config',
  'scripts',
  'sass',
  'watch'
]);

gulp.task('package', [
  'config',
  'clean',
  'scripts:prod',
  'sass'
]);
<|endoftext|>


<commit_before>var async= require('async'),
    _= require('underscore'),
    colors= require('colors');

module.exports= function (dyn)
{
    var finder= {};

    finder.canFind= function (query)
    {
         query.table.indexes.some(function (ind)
         {
              if (ind.usable(query.cond))
              {
                query.index= ind;
                return false;
              }
         });

         return !!query.index;
    };

    finder.find= function (query)
    {
       var p= dyn.promise(['results','count']),
           _get= function (item,done)
           {
               dyn.table(query.table.name)
                  .hash('$id',item.$id)
                  .range('$pos',item.$pos)
                  .get(function (loaded)
               {
                  _.extend(item,loaded);
                  done();
               }).error(done);
           };

       console.log(('Query INDEX ('+query.index.name+')').yellow);

       var cursor= query.index.find(query)

       if (query.count)
           cursor.chain(p);
       else
           cursor.results(function (items)
           {
              async.forEach(items,_get,
              function (err)
              {
                  if (err)
                    p.trigger.error(err);
                  else
                    p.trigger.results(items);
              });
           }).error(p.trigger.error);

       return p;

    };

    return finder;
};
<commit_msg>fix projection on indexed query<commit_after>var async= require('async'),
    _= require('underscore'),
    colors= require('colors');

module.exports= function (dyn)
{
    var finder= {};

    finder.canFind= function (query)
    {
         query.table.indexes.some(function (ind)
         {
              if (ind.usable(query.cond))
              {
                query.index= ind;
                return false;
              }
         });

         return !!query.index;
    };

    finder.find= function (query)
    {
console.log(query.projection);
       var p= dyn.promise(['results','count']),
           _get= function (item,done)
           {
               dyn.table(query.table.name)
                  .hash('$id',item.$id)
                  .range('$pos',item.$pos)
                  .get(function (loaded)
               {
                  _.extend(item,loaded);
                  done();
               },{ attrs: query.projection.include }).error(done);
           };

       console.log(('Query INDEX ('+query.index.name+')').yellow);

       var cursor= query.index.find(query)

       if (query.count)
           cursor.chain(p);
       else
           cursor.results(function (items)
           {
              async.forEach(items,_get,
              function (err)
              {
                  if (err)
                    p.trigger.error(err);
                  else
                    p.trigger.results(items);
              });
           }).error(p.trigger.error);

       return p;

    };

    return finder;
};
<|endoftext|>


<commit_before>const utils = require("ethereumjs-util");
const { toBuffer, bufferToHex, setLengthLeft, setLengthRight } = utils;
// const RegReader = artifacts.require("./RegReader.sol");
const userRegInputs = require("../out/userRegInputs.json");
const merkleRoot = require("../out/merkleRoot.json");
const modDayRate = require("../out/modDayRate.json");
const contractConfig = require("../config/contracts.json");
const { DAO_ACTIONS } = require("../constants");
const decimals = contractConfig.default.contracts.MiniMeToken.args[4];
const etr = require("../utils/etr");
require('promise-log')(Promise);

const testUsername0 = "TEST_USER";
const testData0 = userRegInputs[userRegInputs.findIndex(u=>u[0]===testUsername0)];
testData0.splice(-1,1); // remove address
testData0.push(0);      // add merkle root index

console.log(testData0);

//  let testData0_2 = testData0
//  testData0_2[0] = web3.utils.asciiToHex(testData0[0]);

testData0[0] = web3.utils.asciiToHex(testData0[0]);

const testUsername1 = "heliumcraft";//"doppio";
const testData1 = userRegInputs[userRegInputs.findIndex(u=>u[0]===testUsername1)];
var async = require('async');

let accounts;

const account = require("../config/account");
config({
  //node: "http://localhost:8545",
  mnemonic: account.mnemonic
});

console.log("decimals:", decimals);

contract('EthTraderDAO', function() {
    this.timeout(0);
    before(function(done) {
      var contractsConfig = {
        "EthTraderLib": {
          "deploy": true
        },
        "EthTraderDAO": {
          "args": [
            0, merkleRoot, "$MiniMeToken", "$Registry", "$Store"
          ],
          "onDeploy": [
            "MiniMeToken.methods.changeController('$EthTraderDAO').send()",
            "Registry.methods.changeController('$EthTraderDAO').send()",
            "Store.methods.changeController('$EthTraderDAO').send()"
          ]
        },
        "MiniMeToken": {
          "args": [
            "$TokenFactory", 0, 0, "EthTrader Token", decimals, "ETR", false
          ]
        },
        "Registry": {
        },
        "Store": {
          "args": [
            true,
            decimals
          ]
        },
        "TokenFactory": {
          "deploy": false
        },
        "Voting": {
          "deploy": false
        }
      };
      EmbarkSpec.deployAll(contractsConfig, (_accounts) => {
        accounts = _accounts;
        console.log(accounts);
        done();
      });
    });

    it(`check the dao controls store,token, and registry`, (done) => {
        async.waterfall([
          function(next) {
            Store.methods.controller().call().then(function(result) {
              assert.equal(result, EthTraderDAO.address);
              next();
            });
          },
          function(next) {
            Registry.methods.controller().call().then(function(result) {
              assert.equal(result, EthTraderDAO.address);
              next();
            });
          },
          function(next) {
            MiniMeToken.methods.controller().call().then(function(result) {
              assert.equal(result, EthTraderDAO.address);
              next();
            });
          }
        ], done);
    });

    it(`merkle roots[0] matches ${merkleRoot}`, (done) => {
      EthTraderDAO.methods.roots(0).call().then((root) => {
        assert.equal(root, merkleRoot, `merkle roots[0] doesn't match (${root} vs ${merkleRoot})`);
        done();
      });
    });

    it(`validate ${testUsername0} data`, (done) => {
      EthTraderDAO.methods.validate(...testData0).call().then((result) => {
        console.log(result);
        assert.ok(result, `${testUsername0} failed merkle validation`);
        done();
      });
    });

    it(`${testUsername0} was registered`, (done) => {
      EthTraderDAO.methods.register(...testData0).send({from: accounts[0]}).then((result) => {
        EthTraderDAO.methods.registry().call().then((address) => {
          //Registry.at(address).getOwner(testUsername0, (ownerAddress) => {
          Registry.methods.getOwner(web3.utils.asciiToHex(testUsername0)).call().then((ownerAddress) => {
            console.dir(ownerAddress);
            assert.equal(ownerAddress, accounts[0], `${testUsername0} was not registered`);
            done();
          });
        });
      });
    });

    it(`${testUsername0} was endowed ${testData0[1]}`, (done) => {
      EthTraderDAO.methods.token().call().then((tokenAddress) => {
        //MiniMeToken.at(tokenAddress).balanceOf(accounts[0], (amount) => {
        MiniMeToken.methods.balanceOf(accounts[0]).call().then((amount) => {
          assert.equal(amount, testData0[1], `${testUsername0} was not endowed ${testData0[1]} but ${amount} instead`);
          done();
        });
      });
    });

    it(`token transfers are not enabled`, (done) => {
      EthTraderDAO.methods.token().call().then((tokenAddress) => {
        //MiniMeToken.at(tokenAddress).transfersEnabled((enabled) => {
        MiniMeToken.methods.transfersEnabled().call().then((enabled) => {
          assert.equal(enabled, false, `token transfers were not disabled`);
          done();
        });
      });
    });

    //it(`${testUsername1} was registered@2 with new merkle root@1`, () => {
    //  EthTraderDAO.addRoot(merkleRoot, (result) => {
    //    EthTraderDAO.roots(1, (root) => {
    //      assert.equal(root, merkleRoot, `merkle roots[1] doesn't match (${root} vs ${merkleRoot})`);
//
    //      EthTraderDAO.register(...testData1, {from: accounts[1]}, (result) => {
    //        Registry.usernameToAddress(testUsername1, (address) => {
    //          assert.equal(address, accounts[1], `${testUsername1} was not registered@2`);
    //        });
    //      });
    //    });
    //  });
    //    //return EthTraderDAO.deployed()
    //    //    .then( dao => dao.addRoot(merkleRoot) )
    //    //    .then( () => EthTraderDAO.deployed() )
    //    //    .then( dao => dao.roots.call(1) )
    //    //    .then( root => assert.equal(root, merkleRoot, `merkle roots[1] doesn't match (${root} vs ${merkleRoot})`) )
    //    //    .then( tx => EthTraderDAO.deployed() )
    //    //    .then( dao => dao.register(...testData1, {from: accounts[1]}) )
    //    //    .then( tx => Registry.deployed() )
    //    //    .then( registry => registry.usernameToAddress.call(testUsername1) )
    //    //    .then( address => assert.equal(address, accounts[1], `${testUsername1} was not registered@2`) );
    //});

    it(`${testUsername0} initialised a prop:0`, (done) => {
      EthTraderDAO.methods.addProp(DAO_ACTIONS.TOGGLE_TRANSFERABLE.enum, web3.utils.asciiToHex(0)).send().then((results) => {
        EthTraderDAO.methods.props(0).call().then((prop) => {
          // prop is an object in web3.js 1.0
          //assert.equal(prop.length, 7, `return data length mismatch`);
          console.log(prop, etr(1000));
          assert.equal(prop[5], etr(1000), `return data length mismatch`);
          assert.equal(prop[6], undefined, `return data length mismatch`);
          done();
        });
      });
    });

    it(`${testUsername0} weighted vote amount`, (done) => {
        EthTraderDAO.methods.getWeightedVote(web3.utils.asciiToHex(testUsername0), 0).call().then((result) => {
          assert.equal(result, etr(45000), `weight vote is incorrect`);
          done();
        });
    });

    it(`${testUsername0} could vote:0`, (done) => {
      EthTraderDAO.methods.vote(0, 1).send().then((results) => {
        EthTraderDAO.methods.getVoted(0).call().then((voted) => {
          assert.equal(voted, true, `did not register voted`)
          done();
        });
      });
    });

    it(`${testUsername0} enacted prop:0, tokens are transferable`, (done) => {
      EthTraderDAO.methods.enactProp(0).send().then((results) => {
        MiniMeToken.methods.transfersEnabled().call().then((enabled) => {
          assert.equal(enabled, true, `token transfers were not enabled`);
          done();
        });
      });
    });

    it(`${testUsername0} transfer 150 to ${testUsername1}`, (done) => {
      MiniMeToken.methods.transfer(accounts[1], etr(150)).send().then((results) => {
        MiniMeToken.methods.balanceOf(accounts[1]).call().then((balance) => {
          assert.equal(balance, etr(150), `${testUsername1} did not receive 150`);
          done();
        });
      });
    });

    it(`TOKEN_AGE_DAY_CAP is 200`, (done) => {
        Store.methods.values(web3.utils.asciiToHex("TOKEN_AGE_DAY_CAP")).call().then((amount) => {
          amount => assert.equal(amount.valueOf(), etr(200), `TOKEN_AGE_DAY_CAP not 200`);
          done();
        });
    });

    it(`${testUsername0} initialised a prop:1`, (done) => {
        let propData = bufferToHex(Buffer.concat([
          setLengthRight(toBuffer("TOKEN_AGE_DAY_CAP"), 20),
          setLengthLeft(toBuffer(etr(400)), 12)
        ]));

        EthTraderLib.methods.split32_20_12(propData).call().then((results) => {
          EthTraderDAO.methods.addProp(DAO_ACTIONS.SET_VALUE.enum, propData).send().then((results) => {
            done();
          });
        });
    });

    it(`${testUsername0} could vote:1`, (done) => {
      EthTraderDAO.methods.getWeightedVote(web3.utils.asciiToHex(testUsername0), 1).call().then((results) => {
        EthTraderDAO.methods.vote(1, 1).send().then((results) => {
          done();
        });
      });
    });
    it(`${testUsername0} enacted prop:1, TOKEN_AGE_DAY_CAP changed to 400`, (done) => {
      // TODO: re-add this, might be a bug with the test; prop should be added first
      done();

      //EthTraderDAO.enactProp2(1, {gas: 1000000, from: accounts[0]}, (results) => {
      //  console.log(results);
      //  done();
      //  //Store.values("TOKEN_AGE_DAY_CAP", (amount) => {
      //  //  //console.log(amount);
      //  //  assert.equal(amount.toNumber(), 400, `TOKEN_AGE_DAY_CAP not changed to 400`);
      //  //  done();
      //  //});
      //});
    });

    const stake = 1000;
    it(`prop:2 fail loses ${stake} stake`, (done) => {
      // TODO: issue with addProp
      return done();
      let totalSupply;

      MiniMeToken.methods.totalSupply().call().then((amount) => {
        totalSupply = amount.toNumber();

        EthTraderDAO.methods.addProp(DAO_ACTIONS.ENDOW.enum, 0).send({from: web3.eth.defaultAccount}).then((results) => {
          console.log("addProp", results);
          EthTraderDAO.methods.getWeightedVote(testUsername0, 2).call().then((results) => {
            console.log("getWeightedVote", results);
            EthTraderDAO.methods.vote(2, 0).send({from: web3.eth.defaultAccount}).then((results) => {
              console.log("vote", results);
              EthTraderDAO.methods.enactProp(2).send({from: web3.eth.defaultAccount}).then((results) => {
                console.log("enactProp", results);
                MiniMeToken.methods.totalSupply().call().then((amount) => {
                  console.log("totalSupply", results);
                  assert.equal(amount.toNumber(), totalSupply-stake, `totalSupply not reduced by ${stake}`);
                  done();
                });
              });
            });
          });
        });
      });
    });

    it(`prop:3 simple poll`, (done) => {
      // TODO: add assert...
      EthTraderDAO.methods.addProp(DAO_ACTIONS.NONE.enum, web3.utils.asciiToHex(0)).send({from: web3.eth.defaultAccount}).then((results) => {
        EthTraderDAO.methods.getWeightedVote(web3.utils.asciiToHex(testUsername0), web3.utils.asciiToHex(3)).call().then((results) => {
          done();
          // TODO: it's resulting in an invalid opcode error
          //EthTraderDAO.methods.vote(3,7).send().then((results) => {
          //  EthTraderDAO.methods.endPoll(3).send().then((results) => {
          //    EthTraderDAO.methods.getResult(3, 7).call().then((results) => {
          //      done();
          //    });
          //  });
          //});
        });
      });
    });

    it(`get props`, (done) => {
      EthTraderDAO.methods.getProps().call().then((results) => {
        console.log(results);
        done();
      });
    });

//    it(`prop:4 deploy new DAO and upgrade by vote`, () => {
//        let newDAOAddress, tokenAddress, regAddress, storeAddress;
//
//        tokenAddress = MiniMeToken.address;
//        regAddress = Registry.address;
//        storeAddress = Store.address;
//
//        // TODO: convert this
//
//        //return EthTraderDAO.deployed()
//        //    .then( dao => dao.token.call() )
//        //    .then( address => tokenAddress = address )
//        //    .then( () => EthTraderDAO.deployed() )
//        //    .then( dao => dao.registry.call() )
//        //    .then( address => regAddress = address )
//        //    .then( () => EthTraderDAO.deployed() )
//        //    .then( dao => dao.store.call() )
//        //    .then( address => storeAddress = address )
//        //    .then( () => EthTraderDAO.new(0, 0, tokenAddress, regAddress, storeAddress) )
//        //    .then( instance => newDAOAddress = instance.address )
//        //    .then( () => EthTraderDAO.deployed() )
//        //    .then( dao => dao.addProp(DAO_ACTIONS.UPGRADE.enum, newDAOAddress) )
//        //    .then( () => EthTraderDAO.deployed() )
//        //    .then( dao => dao.getWeightedVote(testUsername0, 4) )
//        //    .log()
//        //    .then( () => EthTraderDAO.deployed() )
//        //    .then( dao => dao.vote(4, 1) )
//        //    .then( () => EthTraderDAO.deployed() )
//        //    .then( dao => dao.enactProp(4) )
//        //    .then( () => EthTraderDAO.deployed() )
//        //    .then( dao => dao.registry.call() )
//        //    .then( address => Registry.at(address).controller.call() )
//        //    .then( address => assert.equal(address, newDAOAddress, `registry controller was not changed to new DAO address`) );
//    });

});
<commit_msg>use development mnemonic for test<commit_after>const utils = require("ethereumjs-util");
const { toBuffer, bufferToHex, setLengthLeft, setLengthRight } = utils;
// const RegReader = artifacts.require("./RegReader.sol");
const userRegInputs = require("../out/userRegInputs.json");
const merkleRoot = require("../out/merkleRoot.json");
const modDayRate = require("../out/modDayRate.json");
const contractConfig = require("../config/contracts.json");
const { DAO_ACTIONS } = require("../constants");
const decimals = contractConfig.default.contracts.MiniMeToken.args[4];
const etr = require("../utils/etr");
require('promise-log')(Promise);

const testUsername0 = "TEST_USER";
const testData0 = userRegInputs[userRegInputs.findIndex(u=>u[0]===testUsername0)];
testData0.splice(-1,1); // remove address
testData0.push(0);      // add merkle root index

console.log(testData0);

//  let testData0_2 = testData0
//  testData0_2[0] = web3.utils.asciiToHex(testData0[0]);

testData0[0] = web3.utils.asciiToHex(testData0[0]);

const testUsername1 = "heliumcraft";//"doppio";
const testData1 = userRegInputs[userRegInputs.findIndex(u=>u[0]===testUsername1)];
var async = require('async');

let accounts;

const mnemonic = require("../config/blockchain.json").development.simulatorMnemonic;
config({
  //node: "http://localhost:8545",
  mnemonic
});

console.log("decimals:", decimals);

contract('EthTraderDAO', function() {
    this.timeout(0);
    before(function(done) {
      var contractsConfig = {
        "EthTraderLib": {
          "deploy": true
        },
        "EthTraderDAO": {
          "args": [
            0, merkleRoot, "$MiniMeToken", "$Registry", "$Store"
          ],
          "onDeploy": [
            "MiniMeToken.methods.changeController('$EthTraderDAO').send()",
            "Registry.methods.changeController('$EthTraderDAO').send()",
            "Store.methods.changeController('$EthTraderDAO').send()"
          ]
        },
        "MiniMeToken": {
          "args": [
            "$TokenFactory", 0, 0, "EthTrader Token", decimals, "ETR", false
          ]
        },
        "Registry": {
        },
        "Store": {
          "args": [
            true,
            decimals
          ]
        },
        "TokenFactory": {
          "deploy": false
        },
        "Voting": {
          "deploy": false
        }
      };
      EmbarkSpec.deployAll(contractsConfig, (_accounts) => {
        accounts = _accounts;
        console.log(accounts);
        done();
      });
    });

    it(`check the dao controls store,token, and registry`, (done) => {
        async.waterfall([
          function(next) {
            Store.methods.controller().call().then(function(result) {
              assert.equal(result, EthTraderDAO.address);
              next();
            });
          },
          function(next) {
            Registry.methods.controller().call().then(function(result) {
              assert.equal(result, EthTraderDAO.address);
              next();
            });
          },
          function(next) {
            MiniMeToken.methods.controller().call().then(function(result) {
              assert.equal(result, EthTraderDAO.address);
              next();
            });
          }
        ], done);
    });

    it(`merkle roots[0] matches ${merkleRoot}`, (done) => {
      EthTraderDAO.methods.roots(0).call().then((root) => {
        assert.equal(root, merkleRoot, `merkle roots[0] doesn't match (${root} vs ${merkleRoot})`);
        done();
      });
    });

    it(`validate ${testUsername0} data`, (done) => {
      EthTraderDAO.methods.validate(...testData0).call().then((result) => {
        console.log(result);
        assert.ok(result, `${testUsername0} failed merkle validation`);
        done();
      });
    });

    it(`${testUsername0} was registered`, (done) => {
      EthTraderDAO.methods.register(...testData0).send({from: accounts[0]}).then((result) => {
        EthTraderDAO.methods.registry().call().then((address) => {
          //Registry.at(address).getOwner(testUsername0, (ownerAddress) => {
          Registry.methods.getOwner(web3.utils.asciiToHex(testUsername0)).call().then((ownerAddress) => {
            console.dir(ownerAddress);
            assert.equal(ownerAddress, accounts[0], `${testUsername0} was not registered`);
            done();
          });
        });
      });
    });

    it(`${testUsername0} was endowed ${testData0[1]}`, (done) => {
      EthTraderDAO.methods.token().call().then((tokenAddress) => {
        //MiniMeToken.at(tokenAddress).balanceOf(accounts[0], (amount) => {
        MiniMeToken.methods.balanceOf(accounts[0]).call().then((amount) => {
          assert.equal(amount, testData0[1], `${testUsername0} was not endowed ${testData0[1]} but ${amount} instead`);
          done();
        });
      });
    });

    it(`token transfers are not enabled`, (done) => {
      EthTraderDAO.methods.token().call().then((tokenAddress) => {
        //MiniMeToken.at(tokenAddress).transfersEnabled((enabled) => {
        MiniMeToken.methods.transfersEnabled().call().then((enabled) => {
          assert.equal(enabled, false, `token transfers were not disabled`);
          done();
        });
      });
    });

    //it(`${testUsername1} was registered@2 with new merkle root@1`, () => {
    //  EthTraderDAO.addRoot(merkleRoot, (result) => {
    //    EthTraderDAO.roots(1, (root) => {
    //      assert.equal(root, merkleRoot, `merkle roots[1] doesn't match (${root} vs ${merkleRoot})`);
//
    //      EthTraderDAO.register(...testData1, {from: accounts[1]}, (result) => {
    //        Registry.usernameToAddress(testUsername1, (address) => {
    //          assert.equal(address, accounts[1], `${testUsername1} was not registered@2`);
    //        });
    //      });
    //    });
    //  });
    //    //return EthTraderDAO.deployed()
    //    //    .then( dao => dao.addRoot(merkleRoot) )
    //    //    .then( () => EthTraderDAO.deployed() )
    //    //    .then( dao => dao.roots.call(1) )
    //    //    .then( root => assert.equal(root, merkleRoot, `merkle roots[1] doesn't match (${root} vs ${merkleRoot})`) )
    //    //    .then( tx => EthTraderDAO.deployed() )
    //    //    .then( dao => dao.register(...testData1, {from: accounts[1]}) )
    //    //    .then( tx => Registry.deployed() )
    //    //    .then( registry => registry.usernameToAddress.call(testUsername1) )
    //    //    .then( address => assert.equal(address, accounts[1], `${testUsername1} was not registered@2`) );
    //});

    it(`${testUsername0} initialised a prop:0`, (done) => {
      EthTraderDAO.methods.addProp(DAO_ACTIONS.TOGGLE_TRANSFERABLE.enum, web3.utils.asciiToHex(0)).send().then((results) => {
        EthTraderDAO.methods.props(0).call().then((prop) => {
          // prop is an object in web3.js 1.0
          //assert.equal(prop.length, 7, `return data length mismatch`);
          console.log(prop, etr(1000));
          assert.equal(prop[5], etr(1000), `return data length mismatch`);
          assert.equal(prop[6], undefined, `return data length mismatch`);
          done();
        });
      });
    });

    it(`${testUsername0} weighted vote amount`, (done) => {
        EthTraderDAO.methods.getWeightedVote(web3.utils.asciiToHex(testUsername0), 0).call().then((result) => {
          assert.equal(result, etr(45000), `weight vote is incorrect`);
          done();
        });
    });

    it(`${testUsername0} could vote:0`, (done) => {
      EthTraderDAO.methods.vote(0, 1).send().then((results) => {
        EthTraderDAO.methods.getVoted(0).call().then((voted) => {
          assert.equal(voted, true, `did not register voted`)
          done();
        });
      });
    });

    it(`${testUsername0} enacted prop:0, tokens are transferable`, (done) => {
      EthTraderDAO.methods.enactProp(0).send().then((results) => {
        MiniMeToken.methods.transfersEnabled().call().then((enabled) => {
          assert.equal(enabled, true, `token transfers were not enabled`);
          done();
        });
      });
    });

    it(`${testUsername0} transfer 150 to ${testUsername1}`, (done) => {
      MiniMeToken.methods.transfer(accounts[1], etr(150)).send().then((results) => {
        MiniMeToken.methods.balanceOf(accounts[1]).call().then((balance) => {
          assert.equal(balance, etr(150), `${testUsername1} did not receive 150`);
          done();
        });
      });
    });

    it(`TOKEN_AGE_DAY_CAP is 200`, (done) => {
        Store.methods.values(web3.utils.asciiToHex("TOKEN_AGE_DAY_CAP")).call().then((amount) => {
          amount => assert.equal(amount.valueOf(), etr(200), `TOKEN_AGE_DAY_CAP not 200`);
          done();
        });
    });

    it(`${testUsername0} initialised a prop:1`, (done) => {
        let propData = bufferToHex(Buffer.concat([
          setLengthRight(toBuffer("TOKEN_AGE_DAY_CAP"), 20),
          setLengthLeft(toBuffer(etr(400)), 12)
        ]));

        EthTraderLib.methods.split32_20_12(propData).call().then((results) => {
          EthTraderDAO.methods.addProp(DAO_ACTIONS.SET_VALUE.enum, propData).send().then((results) => {
            done();
          });
        });
    });

    it(`${testUsername0} could vote:1`, (done) => {
      EthTraderDAO.methods.getWeightedVote(web3.utils.asciiToHex(testUsername0), 1).call().then((results) => {
        EthTraderDAO.methods.vote(1, 1).send().then((results) => {
          done();
        });
      });
    });
    it(`${testUsername0} enacted prop:1, TOKEN_AGE_DAY_CAP changed to 400`, (done) => {
      // TODO: re-add this, might be a bug with the test; prop should be added first
      done();

      //EthTraderDAO.enactProp2(1, {gas: 1000000, from: accounts[0]}, (results) => {
      //  console.log(results);
      //  done();
      //  //Store.values("TOKEN_AGE_DAY_CAP", (amount) => {
      //  //  //console.log(amount);
      //  //  assert.equal(amount.toNumber(), 400, `TOKEN_AGE_DAY_CAP not changed to 400`);
      //  //  done();
      //  //});
      //});
    });

    const stake = 1000;
    it(`prop:2 fail loses ${stake} stake`, (done) => {
      // TODO: issue with addProp
      return done();
      let totalSupply;

      MiniMeToken.methods.totalSupply().call().then((amount) => {
        totalSupply = amount.toNumber();

        EthTraderDAO.methods.addProp(DAO_ACTIONS.ENDOW.enum, 0).send({from: web3.eth.defaultAccount}).then((results) => {
          console.log("addProp", results);
          EthTraderDAO.methods.getWeightedVote(testUsername0, 2).call().then((results) => {
            console.log("getWeightedVote", results);
            EthTraderDAO.methods.vote(2, 0).send({from: web3.eth.defaultAccount}).then((results) => {
              console.log("vote", results);
              EthTraderDAO.methods.enactProp(2).send({from: web3.eth.defaultAccount}).then((results) => {
                console.log("enactProp", results);
                MiniMeToken.methods.totalSupply().call().then((amount) => {
                  console.log("totalSupply", results);
                  assert.equal(amount.toNumber(), totalSupply-stake, `totalSupply not reduced by ${stake}`);
                  done();
                });
              });
            });
          });
        });
      });
    });

    it(`prop:3 simple poll`, (done) => {
      // TODO: add assert...
      EthTraderDAO.methods.addProp(DAO_ACTIONS.NONE.enum, web3.utils.asciiToHex(0)).send({from: web3.eth.defaultAccount}).then((results) => {
        EthTraderDAO.methods.getWeightedVote(web3.utils.asciiToHex(testUsername0), web3.utils.asciiToHex(3)).call().then((results) => {
          done();
          // TODO: it's resulting in an invalid opcode error
          //EthTraderDAO.methods.vote(3,7).send().then((results) => {
          //  EthTraderDAO.methods.endPoll(3).send().then((results) => {
          //    EthTraderDAO.methods.getResult(3, 7).call().then((results) => {
          //      done();
          //    });
          //  });
          //});
        });
      });
    });

    it(`get props`, (done) => {
      EthTraderDAO.methods.getProps().call().then((results) => {
        console.log(results);
        done();
      });
    });

//    it(`prop:4 deploy new DAO and upgrade by vote`, () => {
//        let newDAOAddress, tokenAddress, regAddress, storeAddress;
//
//        tokenAddress = MiniMeToken.address;
//        regAddress = Registry.address;
//        storeAddress = Store.address;
//
//        // TODO: convert this
//
//        //return EthTraderDAO.deployed()
//        //    .then( dao => dao.token.call() )
//        //    .then( address => tokenAddress = address )
//        //    .then( () => EthTraderDAO.deployed() )
//        //    .then( dao => dao.registry.call() )
//        //    .then( address => regAddress = address )
//        //    .then( () => EthTraderDAO.deployed() )
//        //    .then( dao => dao.store.call() )
//        //    .then( address => storeAddress = address )
//        //    .then( () => EthTraderDAO.new(0, 0, tokenAddress, regAddress, storeAddress) )
//        //    .then( instance => newDAOAddress = instance.address )
//        //    .then( () => EthTraderDAO.deployed() )
//        //    .then( dao => dao.addProp(DAO_ACTIONS.UPGRADE.enum, newDAOAddress) )
//        //    .then( () => EthTraderDAO.deployed() )
//        //    .then( dao => dao.getWeightedVote(testUsername0, 4) )
//        //    .log()
//        //    .then( () => EthTraderDAO.deployed() )
//        //    .then( dao => dao.vote(4, 1) )
//        //    .then( () => EthTraderDAO.deployed() )
//        //    .then( dao => dao.enactProp(4) )
//        //    .then( () => EthTraderDAO.deployed() )
//        //    .then( dao => dao.registry.call() )
//        //    .then( address => Registry.at(address).controller.call() )
//        //    .then( address => assert.equal(address, newDAOAddress, `registry controller was not changed to new DAO address`) );
//    });

});
<|endoftext|>


<commit_before>var _ = require('lodash');
var moment = require('moment');
var Promise = require('bluebird');
var mongodb = Promise.promisifyAll(require('mongodb'));
var debug = require('debug')('lib:mongo');
var debugread = require('debug')('lib:mongo:read');
var debugcount = require('debug')('lib:mongo:count');
var nconf = require('nconf');

var dbConnection = function() {
    var url = nconf.get('mongodb');
    // debug("using mongourl %s", url);
    return mongodb
        .MongoClient
        .connectAsync(url)
        .disposer(function(db) {
            return db.close();
        });
};

function doesMongoWorks() {
    return Promise.using(dbConnection(), function(db) {
        return db
            .listCollections()
            .toArray();
    })
    .map(function(entry) {
        return _.get(entry, 'name');
    });
};

var writeOne = function(cName, dataObject) {
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .insert(dataObject);
    })
    .return(dataObject);
};

var updateOne = function(cName, selector, updated) {
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .updateOne(selector, updated);
    })
    .tap(function(ret) {
        debug("updateOne by %j: %j", selector, ret);
    })
    .return(updated);
};

/* better safe than sorry */
var upsertOne = function(cName, selector, updated) {
    debug("upserting in [%s] by %j", cName, selector);
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .updateOne(selector, updated, {upsert: true});
    })
    .return(updated);
};

function writeMany(cName, dataObjects) {
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .insertMany(dataObjects);
    })
};

function readOne(cName, selector, sorter) {
    return read(cName, selector, sorter)
        .then(_.first);
};

function read(cName, selector, sorter) {
    if(_.isUndefined(sorter)) sorter = {};
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .find(selector)
            .sort(sorter)
            .toArray();
    })
    .tap(function(rv) {
        debugread("R %s %j → %d objs", cName, selector, _.size(rv));
    });
};

function remove(cName, selector) {

    if(_.size(_.keys(selector)) === 0)
        throw new Error("Nope, you can't delete {} ");

    debug("Removing documents %j from %s", selector, cName);
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .remove(selector);
    })
};

var readLimit = function(cName, selector, sorter, limitN, past) {
    if(_.isNaN(past)) past = 0;
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .find(selector)
            .sort(sorter)
            .skip(past)
            .limit(limitN)
            .toArray()
    })
    .tap(function(rv) {
        debugread("RL %s %j %s %s →  %d objs", cName, selector,
            limitN ? "limit " + limitN : "",
            past ? "skip " + past : "",
            _.size(rv)
        );
    })
    .catch(function(errstr) {
        debug("Error in readLimit!: %s", errstr);
        return [];
    });
};

function count(cName, selector) {
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .count(selector);
    })
    .tap(function(result) {
        debugcount("count in %s by %j = %d", cName, selector, result);
    });
};

function grouping(cName, match, group) {
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .grouping([
                { $match: match },
                { $group: group }
            ])
            .toArray();
    })
    .tap(function(ret) {
        debug("grouping %s match %s group %s → %d entries",
            cName, JSON.stringify(match),
            JSON.stringify(group), _.size(ret));
    })
};

function aggregate(cName, pipeline) {
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .aggregate(pipeline)
            .toArray();
    })
    .tap(function(ret) {
        debug("aggregate in %s pipeline %j results for %d entry",
            cName, _.map(pipeline, _.keys), _.size(ret)
        );
    })
};

var countByDay = function(cName, timeVarName, filter, aggext) {

    if(!_.startsWith(timeVarName, '$'))
        throw new Error("developer please: mongoVar wants '$'");

    var queryId = {
        year:  { $year: timeVarName },
        month: { $month: timeVarName },
        day:   { $dayOfMonth: timeVarName }
    };

    if(_.isObject(aggext) && _.size(_.keys(aggext)) > 0) {
        /* for example: { user: "$userId" } */
        queryId = _.extend(queryId, aggext);
    }

    var totalQ = [
        { $match: filter },
        { $group: {
            _id: queryId,
            count: { $sum: 1 }
        }}];

    debug("countByDay on %s %j  → ", cName, filter);
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .grouping(totalQ)
            .toArray()
            .catch(function(error) {
                debug("countByDay error: %s (%s)", error, cName);
                return [];
            });
    })
    .tap(function(done) {
        debug("← countByDay on %s F %j[%j] got %d",
            cName, filter, aggext, _.size(done));
    });
};

var countByObject = function(cName, idobj) {
    if(_.isUndefined(idobj)) idobj = {};
    debug("countByObject in %s by %j", cName, idobj);
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .grouping([
                {
                  $group: {
                    _id: idobj,
                    count: { $sum: 1 }
                  }
                },
                { $sort: { count: -1 } }
            ])
            .toArray()
            .catch(function(error) {
                debug("countByObject error: %s (%s)", error, cName);
                return [];
            });
    })
};

function lookup(cName, query, sequence) {
    // debug("lookup on %s of %j + %j", cName, query, sequence);

    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .grouping([ query, sequence ])
            .toArray()
            .catch(function(error) {
                debug("lookup in %s error: %s", cName, error);
                return [];
            });
    })
};

function save(cName, doc) {
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .save(doc);
    });
};

function createIndex(cName, index, opt) {
    return Promise.using(dbConnection(), function(db) {
        return db.ensureIndex(cName, index, opt);
    })
    .tap(function(results) {
        debug("indexes created on %s: %j = %j", cName, index, results);
    });
};

function distinct(cName, field, query) {
    debug("distinct in %s for %s with %j", cName, field, query);
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .distinct(field, query);
    })
    .tap(function(results) {
        debug("distinct on %s, on %s: %d elements", cName, field, _.size(results));
    });
};

module.exports = {
    doesMongoWorks: doesMongoWorks,
    updateOne: updateOne,
    upsertOne: upsertOne,
    writeOne: writeOne,
    writeMany: writeMany,
    readLimit: readLimit,
    countByDay: countByDay,
    count: count,
    countByObject: countByObject,
    read: read,
    readOne: readOne,
    remove: remove,
    grouping: grouping,
    aggregate: aggregate,
    lookup: lookup,
    save: save,
    createIndex: createIndex,
    distinct: distinct
};

<commit_msg>uniformed syntax<commit_after>var _ = require('lodash');
var moment = require('moment');
var Promise = require('bluebird');
var mongodb = Promise.promisifyAll(require('mongodb'));
var debug = require('debug')('lib:mongo');
var debugread = require('debug')('lib:mongo:read');
var debugcount = require('debug')('lib:mongo:count');
var nconf = require('nconf');

function dbConnection() {
    var url = nconf.get('mongodb');
    // debug("using mongourl %s", url);
    return mongodb
        .MongoClient
        .connectAsync(url)
        .disposer(function(db) {
            return db.close();
        });
};

function doesMongoWorks() {
    return Promise.using(dbConnection(), function(db) {
        return db
            .listCollections()
            .toArray();
    })
    .map(function(entry) {
        return _.get(entry, 'name');
    });
};

function writeOne(cName, dataObject) {
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .insert(dataObject);
    })
    .return(dataObject);
};

function updateOne(cName, selector, updated) {
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .updateOne(selector, updated);
    })
    .tap(function(ret) {
        debug("updateOne by %j: %j", selector, ret);
    })
    .return(updated);
};

/* better safe than sorry */
function upsertOne(cName, selector, updated) {
    debug("upserting in [%s] by %j", cName, selector);
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .updateOne(selector, updated, {upsert: true});
    })
    .return(updated);
};

function writeMany(cName, dataObjects) {
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .insertMany(dataObjects);
    })
};

function readOne(cName, selector, sorter) {
    return read(cName, selector, sorter)
        .then(_.first);
};

function read(cName, selector, sorter) {
    if(_.isUndefined(sorter)) sorter = {};
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .find(selector)
            .sort(sorter)
            .toArray();
    })
    .tap(function(rv) {
        debugread("R %s %j → %d objs", cName, selector, _.size(rv));
    });
};

function remove(cName, selector) {

    if(_.size(_.keys(selector)) === 0)
        throw new Error("Nope, you can't delete {} ");

    debug("Removing documents %j from %s", selector, cName);
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .remove(selector);
    })
};

function readLimit(cName, selector, sorter, limitN, past) {
    if(_.isNaN(past)) past = 0;
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .find(selector)
            .sort(sorter)
            .skip(past)
            .limit(limitN)
            .toArray()
    })
    .tap(function(rv) {
        debugread("RL %s %j %s %s →  %d objs", cName, selector,
            limitN ? "limit " + limitN : "",
            past ? "skip " + past : "",
            _.size(rv)
        );
    })
    .catch(function(errstr) {
        debug("Error in readLimit!: %s", errstr);
        return [];
    });
};

function count(cName, selector) {
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .count(selector);
    })
    .tap(function(result) {
        debugcount("count in %s by %j = %d", cName, selector, result);
    });
};

function grouping(cName, match, group) {
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .grouping([
                { $match: match },
                { $group: group }
            ])
            .toArray();
    })
    .tap(function(ret) {
        debug("grouping %s match %s group %s → %d entries",
            cName, JSON.stringify(match),
            JSON.stringify(group), _.size(ret));
    })
};

function aggregate(cName, pipeline) {
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .aggregate(pipeline)
            .toArray();
    })
    .tap(function(ret) {
        debug("aggregate in %s pipeline %j results for %d entry",
            cName, _.map(pipeline, _.keys), _.size(ret)
        );
    })
};

function countByDay(cName, timeVarName, filter, aggext) {

    if(!_.startsWith(timeVarName, '$'))
        throw new Error("developer please: mongoVar wants '$'");

    var queryId = {
        year:  { $year: timeVarName },
        month: { $month: timeVarName },
        day:   { $dayOfMonth: timeVarName }
    };

    if(_.isObject(aggext) && _.size(_.keys(aggext)) > 0) {
        /* for example: { user: "$userId" } */
        queryId = _.extend(queryId, aggext);
    }

    var totalQ = [
        { $match: filter },
        { $group: {
            _id: queryId,
            count: { $sum: 1 }
        }}];

    debug("countByDay on %s %j  → ", cName, filter);
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .grouping(totalQ)
            .toArray()
            .catch(function(error) {
                debug("countByDay error: %s (%s)", error, cName);
                return [];
            });
    })
    .tap(function(done) {
        debug("← countByDay on %s F %j[%j] got %d",
            cName, filter, aggext, _.size(done));
    });
};

function countByObject(cName, idobj) {
    if(_.isUndefined(idobj)) idobj = {};
    debug("countByObject in %s by %j", cName, idobj);
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .grouping([
                {
                  $group: {
                    _id: idobj,
                    count: { $sum: 1 }
                  }
                },
                { $sort: { count: -1 } }
            ])
            .toArray()
            .catch(function(error) {
                debug("countByObject error: %s (%s)", error, cName);
                return [];
            });
    })
};

function lookup(cName, query, sequence) {
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .grouping([ query, sequence ])
            .toArray()
            .catch(function(error) {
                debug("lookup in %s error: %s", cName, error);
                return [];
            });
    })
    .tap(function(r) {
        debug("lookup on %s of %j + %j →  %d",
            cName, query, sequence, _.size(r) );
    });
};

function save(cName, doc) {
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .save(doc);
    });
};

function createIndex(cName, index, opt) {
    return Promise.using(dbConnection(), function(db) {
        return db.ensureIndex(cName, index, opt);
    })
    .tap(function(results) {
        debug("indexes created on %s: %j = %j", cName, index, results);
    });
};

function distinct(cName, field, query) {
    debug("distinct in %s for %s with %j", cName, field, query);
    return Promise.using(dbConnection(), function(db) {
        return db
            .collection(cName)
            .distinct(field, query);
    })
    .tap(function(results) {
        debug("distinct on %s, on %s: %d elements", cName, field, _.size(results));
    });
};

module.exports = {
    doesMongoWorks: doesMongoWorks,
    updateOne: updateOne,
    upsertOne: upsertOne,
    writeOne: writeOne,
    writeMany: writeMany,
    readLimit: readLimit,
    countByDay: countByDay,
    count: count,
    countByObject: countByObject,
    read: read,
    readOne: readOne,
    remove: remove,
    grouping: grouping,
    aggregate: aggregate,
    lookup: lookup,
    save: save,
    createIndex: createIndex,
    distinct: distinct
};

<|endoftext|>


<commit_before>/**
 * Created by alejandro on 5/03/17.
 */

const express = require('express');
const router = express.Router();
const config = require('../config/config');
const recast = require('recastai');
const request = require('request');
const util = require('util');

var capture = require('../models/capture');
var shoe = require('../models/shoe');

const getGreetings = require('../intents/greetings');
const getAskForModel= require('../intents/askformodel');
//const getNotUnderstood = require('../intents/notUnderstood');

const recastClient = new recast.Client(config.recast_dev);

const INTENTS = {
    greetings: getGreetings,
    askformodel: getAskForModel
};

var randomBegin = ["It appears to be ", "Oh! These are ", "I'm so confident these are ", "Ok, I have found that these are ",
    "Wait a moment! These are the new "];

var randomEnd = [""];

router.get('', function(req, res) {
    if (req.query['hub.mode'] === 'subscribe' &&
        req.query['hub.verify_token'] === config.verify_token) {
        console.log("Validating webhook");
        res.status(200).send(req.query['hub.challenge']);
    } else {
        console.error("Failed validation. Make sure the validation tokens match.");
        res.sendStatus(403);
    }
});

router.post('', function (req, res) {

    var data = req.body;

    // Make sure this is a page subscription
    if (data.object === 'page') {

        // Iterate over each entry - there may be multiple if batched
        data.entry.forEach(function(entry) {
            var pageID = entry.id;
            var timeOfEvent = entry.time;

            // Iterate over each messaging event
            entry.messaging.forEach(function(event) {

                if(event.postback){
                    console.log(event);
                    managePostBack(event);
                } else if (event.message) {
                    receivedMessage(event);
                } else {
                    console.log("Webhook received unknown event: ", event);
                }
            });
        });

        // Assume all went well.
        //
        // You must send back a 200, within 20 seconds, to let us know
        // you've successfully received the callback. Otherwise, the request
        // will time out and we will keep trying to resend.
        res.sendStatus(200);
    }
});

function receivedMessage(event) {

    var senderID = event.sender.id;

    sendLoading(senderID);

    //TODO: Hacer algo con el nombre del usuario (y mas info)
    console.log("Llamando a fb");
    request({
        uri: 'https://graph.facebook.com/v2.6/' + senderID,
        qs: { access_token: config.page_token },
        method: 'GET'
    }, function (error, response, body) {
        if (!error && response.statusCode == 200) {

            var userName = JSON.parse(body).first_name;
            var recipientID = event.recipient.id;
            var timeOfMessage = event.timestamp;
            var message = event.message;

            console.log("Received message for user %d and page %d at %d with message:",
                senderID, recipientID, timeOfMessage);
            console.log(JSON.stringify(message));

            var messageId = message.mid;

            var messageText = message.text;
            var messageAttachments = message.attachments;

            if (messageAttachments) {
                processAttachment(senderID, messageAttachments, userName);
            } else if(isUrl(messageText)){
                processUrl(senderID, messageText, userName);
            } else if (messageText) {

                recastClient.textRequest(messageText)
                    .then(res => {
                        const intent = res.intent();
                        if (intent != null) {
                            console.log("HOSTIA PUTA YA " + intent.slug)
                            switch (intent.slug) {
                                case 'greetings':
                                    console.log("Sí es un saludo");
                                    sendTextMessage(senderID, INTENTS[intent.slug]());
                                    break;
                                case 'askformodel':
                                    console.log('Está pidiendo info de un modelo');
                                    sendTextMessage(senderID, INTENTS[intent.slug]());
                                    sendLoading(senderID);
                                    sendCardMessage(senderID);
                                    break;
                                default:
                                    console.log("No es un saludo");
                                    sendTextMessage(senderID, "gilipollas");
                                    break;
                            }
                        } else {
                            console.log("No es un saludo");
                            sendTextMessage(senderID, "gilipollas");
                        }
                    })
                    .catch((err) => {
                        console.log(err);
                        sendTextMessage(senderID, 'I need some sleep right now... Talk to me later!');
                    });
            }
        } else {
            console.error("Unable to find user");
        }
    });
}

function processAttachment(senderID, messageAttachments, userName){
    console.log(messageAttachments);

    // Iterate over each entry - there may be multiple if batched

    messageAttachments.forEach(function(attachment) {
        var imageUrl = attachment.payload.url;
        switch (attachment.type) {
            case "fallback":
                imageUrl = attachment.url;
                imageUrl = imageUrl.replace("https://l.facebook.com/l.php?u=", "");
                imageUrl = decodeURIComponent(imageUrl);
            case "image":
                var exec = require('child_process').exec;

                var cmd = 'python ../main.py ' + "\"" + imageUrl + "\"";
                var newCapture = new capture();
                exec(cmd, function (error, stdout, stderr) {
                    console.log("Error" + error);
                    console.log("Stdout: " + stdout);
                    var firstLine = stdout.split('\n')[0];
                    console.log("First Line: " + firstLine);
                    var arr = firstLine.split(" ");
                    console.log("Arr: " + arr);
                    switch (arr[0]) {
                        case "bb1302":
                            newCapture.code = "bb1302";
                            break;
                        case "zxflux":
                            newCapture.code = "zxflux";
                            break;
                        case "c77124":
                            newCapture.code = "c77124";
                            break;
                        case "ba8278":
                            newCapture.code = "ba8278";
                            break;
                        case "bb0008":
                            newCapture.code = "bb0008";
                            break;
                        case "bb5477":
                            newCapture.code = "bb5477";
                            break;
                        case "boost":
                            newCapture.code = "boost";
                            break;
                        case "adidas":
                            newCapture.code = "adidas";
                            break;
                        default:
                            break;
                    }
                    newCapture.id = senderID;
                    newCapture.name = userName;
                    newCapture.score = parseFloat(arr[3].replace(')', ''));
                    newCapture.save(function (err, data) {
                        if (err) {
                            console.log(err);
                        }
                        console.log(newCapture);
                        shoe.findOne({'code': newCapture.code}, function (err, data) {
                            if (err) {
                                //Error servidor
                                response = {"error": true, "message": "Fetching error"};
                                res.status(500).json(response);
                            } else {
                                var randBegin = randomBegin[Math.floor(Math.random() * randomBegin.length)];
                                var response = randBegin + "\"" + data.name + "\"" + ". " + data.description
                                    + ". You have them for " + data.price + "$ at adidas.com";
                                sendTextMessage(senderID, response);
                            }
                        })
                    });
                    console.log(stdout);
                    console.log(stderr);
                });
                break;
            default:
                sendTextMessage(senderID, "I don't know about this...");
                break;
        }
    });

}

function processUrl(senderID, messageAttachments, userName){
    console.log(messageAttachments);
    var exec = require('child_process').exec;

    var cmd = 'python ../main.py ' + "\"" + messageAttachments + "\"";
    var newCapture = new capture();
    exec(cmd, function (error, stdout, stderr) {
        console.log("Error" + error);
        console.log("Stdout: " + stdout);
        var firstLine = stdout.split('\n')[0];
        console.log("First Line: " + firstLine);
        var arr = firstLine.split(" ");
        console.log("Arr: " + arr);
        switch (arr[0]) {
            case "bb1302":
                newCapture.code = "bb1302";
                break;
            case "zxflux":
                newCapture.code = "zxflux";
                break;
            case "c77124":
                newCapture.code = "c77124";
                break;
            case "ba8278":
                newCapture.code = "ba8278";
                break;
            case "bb0008":
                newCapture.code = "bb0008";
                break;
            case "bb5477":
                newCapture.code = "bb5477";
                break;
            case "boost":
                newCapture.code = "boost";
                break;
            case "adidas":
                newCapture.code = "adidas";
                break;
            case "invalid":
                newCapture.code = "invalid";
                break;
            default:
                break;
        }
        if (newCapture.code == "invalid") {
            sendTextMessage(senderID, "I don't know about this...");
        } else {
            newCapture.id = senderID;
            newCapture.name = userName;
            newCapture.score = parseFloat(arr[3].replace(')', ''));
            newCapture.save(function (err, data) {
                if (err) {
                    console.log(err);
                }
                console.log(newCapture);
                shoe.findOne({'code': newCapture.code}, function (err, data) {
                    if (err) {
                        //Error servidor
                        response = {"error": true, "message": "Fetching error"};
                        res.status(500).json(response);
                    } else {
                        var randBegin = randomBegin[Math.floor(Math.random() * randomBegin.length)];
                        var response = randBegin + "\"" + data.name + "\"" + ". " + data.description
                            + ". You have them for " + data.price + "$ at adidas.com";
                        sendTextMessage(senderID, response);
                    }
                })
            });
            console.log(stdout);
        }
    });
}

function sendGenericMessage(recipientId, messageText) {
    // To be expanded in later sections
}

function managePostBack(event){
    var senderID = event.sender.id;
    var recipientID = event.recipient.id;
    var timeOfPostback = event.timestamp;

    // The 'payload' param is a developer-defined field which is set in a postback
    // button for Structured Messages.
    var payload = event.postback.payload;

    console.log("Received postback for user %d and page %d with payload '%s' " +
        "at %d", senderID, recipientID, payload, timeOfPostback);

    // When a postback is called, we'll send a message back to the sender to
    // let them know it was successful
    sendTextMessage(senderID, JSON.parse(event.postback.payload).text);
}

function sendCardMessage(recipientId/*, trainer*/){
    var messageData = {
        recipient: {
            id: recipientId
        },
        message: {
            attachment: {
                type: "template",
                payload: {
                    template_type: "generic",
                    elements: [{
                        title: "ZAPATILLA X_PLR",
                        item_url: "http://www.adidas.es/zapatilla-x_plr/BB1100.html?pr=home_rr&slot=2",
                        image_url: "http://www.adidas.es/dis/dw/image/v2/aagl_prd/on/demandware.static/-/Sites-adidas-products/default/dw4863d725/zoom/BB1100_01_standard.jpg?sw=500&sfrm=jpg",
                        buttons: [{
                            type: "web_url",
                            url: "http://www.adidas.es/zapatilla-x_plr/BB1100.html?pr=home_rr&slot=2",
                            title: "Go to shop"
                        }, {
                            type: "postback",
                            title: "Show more info",
                            payload: '{ "name": "Zapatilla x_plr", "text": "jajajaja xddd"}'
                        }],
                    }]
                }
            }
        }/*
        message: {
            attachment: {
                type: "template",
                payload: {
                    template_type: "generic",
                    elements: [{
                        title: trainer.name,
                        item_url: trainer.itemUrl,
                        image_url: trainer.imageUrl,
                        buttons: [{
                            type: "web_url",
                            url: trainer.itemUrl,
                            title: "Go to shop"
                        }, {
                            type: "postback",
                            title: "Show more info",
                            payload: "Show more info",
                        }],
                    }, {
                        title: "touch",
                        subtitle: "Your Hands, Now in VR",
                        item_url: "https://www.oculus.com/en-us/touch/",
                        image_url: "http://messengerdemo.parseapp.com/img/touch.png",
                        buttons: [{
                            type: "web_url",
                            url: trainer.itemUrl,
                            title: "Open Web URL"
                        }, {
                            type: "postback",
                            title: "Call Postback",
                            payload: "Payload for second bubble",
                        }]
                    }]
                }
            }
        }*/
    };

    callSendAPI(messageData);
}

function sendTextMessage(recipientId, messageText) {
    console.log(messageText);
    var messageData = {
        recipient: {
            id: recipientId
        },
        message: {
            text: messageText
        }
    };

    callSendAPI(messageData);
}

function callSendAPI(messageData) {
    request({
        uri: 'https://graph.facebook.com/v2.6/me/messages',
        qs: { access_token: config.page_token },
        method: 'POST',
        json: messageData

    }, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            var recipientId = body.recipient_id;
            var messageId = body.message_id;

            console.log("Successfully sent generic message with id %s to recipient %s",
                messageId, recipientId);
        } else {
            console.error("Unable to send message.");
            console.error(response);
            console.error(error);
        }
    });
}

function sendLoading(senderID){
    request({
        uri: 'https://graph.facebook.com/v2.6/me/messages',
        qs: { access_token: config.page_token },
        method: 'POST',
        json: {"recipient": {"id": senderID},
            "sender_action":"typing_on"}
    });
}

function isUrl(url){
    var expression = /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi;
    var regex = new RegExp(expression);
    if (url.match(regex)) {
        return true;
    } else {
        return false;
    }
}

module.exports = router;
<commit_msg>Fallback case, bypass facebook redirection<commit_after>/**
 * Created by alejandro on 5/03/17.
 */

const express = require('express');
const router = express.Router();
const config = require('../config/config');
const recast = require('recastai');
const request = require('request');
const util = require('util');

var capture = require('../models/capture');
var shoe = require('../models/shoe');

const getGreetings = require('../intents/greetings');
const getAskForModel= require('../intents/askformodel');
//const getNotUnderstood = require('../intents/notUnderstood');

const recastClient = new recast.Client(config.recast_dev);

const INTENTS = {
    greetings: getGreetings,
    askformodel: getAskForModel
};

var randomBegin = ["It appears to be ", "Oh! These are ", "I'm so confident these are ", "Ok, I have found that these are ",
    "Wait a moment! These are the new "];

var randomEnd = [""];

router.get('', function(req, res) {
    if (req.query['hub.mode'] === 'subscribe' &&
        req.query['hub.verify_token'] === config.verify_token) {
        console.log("Validating webhook");
        res.status(200).send(req.query['hub.challenge']);
    } else {
        console.error("Failed validation. Make sure the validation tokens match.");
        res.sendStatus(403);
    }
});

router.post('', function (req, res) {

    var data = req.body;

    // Make sure this is a page subscription
    if (data.object === 'page') {

        // Iterate over each entry - there may be multiple if batched
        data.entry.forEach(function(entry) {
            var pageID = entry.id;
            var timeOfEvent = entry.time;

            // Iterate over each messaging event
            entry.messaging.forEach(function(event) {

                if(event.postback){
                    console.log(event);
                    managePostBack(event);
                } else if (event.message) {
                    receivedMessage(event);
                } else {
                    console.log("Webhook received unknown event: ", event);
                }
            });
        });

        // Assume all went well.
        //
        // You must send back a 200, within 20 seconds, to let us know
        // you've successfully received the callback. Otherwise, the request
        // will time out and we will keep trying to resend.
        res.sendStatus(200);
    }
});

function receivedMessage(event) {

    var senderID = event.sender.id;

    sendLoading(senderID);

    //TODO: Hacer algo con el nombre del usuario (y mas info)
    console.log("Llamando a fb");
    request({
        uri: 'https://graph.facebook.com/v2.6/' + senderID,
        qs: { access_token: config.page_token },
        method: 'GET'
    }, function (error, response, body) {
        if (!error && response.statusCode == 200) {

            var userName = JSON.parse(body).first_name;
            var recipientID = event.recipient.id;
            var timeOfMessage = event.timestamp;
            var message = event.message;

            console.log("Received message for user %d and page %d at %d with message:",
                senderID, recipientID, timeOfMessage);
            console.log(JSON.stringify(message));

            var messageId = message.mid;

            var messageText = message.text;
            var messageAttachments = message.attachments;

            if (messageAttachments) {
                processAttachment(senderID, messageAttachments, userName);
            } else if(isUrl(messageText)){
                processUrl(senderID, messageText, userName);
            } else if (messageText) {

                recastClient.textRequest(messageText)
                    .then(res => {
                        const intent = res.intent();
                        if (intent != null) {
                            console.log("HOSTIA PUTA YA " + intent.slug)
                            switch (intent.slug) {
                                case 'greetings':
                                    console.log("Sí es un saludo");
                                    sendTextMessage(senderID, INTENTS[intent.slug]());
                                    break;
                                case 'askformodel':
                                    console.log('Está pidiendo info de un modelo');
                                    sendTextMessage(senderID, INTENTS[intent.slug]());
                                    sendLoading(senderID);
                                    sendCardMessage(senderID);
                                    break;
                                default:
                                    console.log("No es un saludo");
                                    sendTextMessage(senderID, "gilipollas");
                                    break;
                            }
                        } else {
                            console.log("No es un saludo");
                            sendTextMessage(senderID, "gilipollas");
                        }
                    })
                    .catch((err) => {
                        console.log(err);
                        sendTextMessage(senderID, 'I need some sleep right now... Talk to me later!');
                    });
            }
        } else {
            console.error("Unable to find user");
        }
    });
}

function processAttachment(senderID, messageAttachments, userName){
    console.log(messageAttachments);

    // Iterate over each entry - there may be multiple if batched

    messageAttachments.forEach(function(attachment) {
        var imageUrl = attachment.url || attachment.payload.url;
        switch (attachment.type) {
            case "fallback":
                imageUrl = attachment.url;
                imageUrl = imageUrl.replace("https://l.facebook.com/l.php?u=", "");
                imageUrl = decodeURIComponent(imageUrl);
            case "image":
                var exec = require('child_process').exec;

                var cmd = 'python ../main.py ' + "\"" + imageUrl + "\"";
                var newCapture = new capture();
                exec(cmd, function (error, stdout, stderr) {
                    console.log("Error" + error);
                    console.log("Stdout: " + stdout);
                    var firstLine = stdout.split('\n')[0];
                    console.log("First Line: " + firstLine);
                    var arr = firstLine.split(" ");
                    console.log("Arr: " + arr);
                    switch (arr[0]) {
                        case "bb1302":
                            newCapture.code = "bb1302";
                            break;
                        case "zxflux":
                            newCapture.code = "zxflux";
                            break;
                        case "c77124":
                            newCapture.code = "c77124";
                            break;
                        case "ba8278":
                            newCapture.code = "ba8278";
                            break;
                        case "bb0008":
                            newCapture.code = "bb0008";
                            break;
                        case "bb5477":
                            newCapture.code = "bb5477";
                            break;
                        case "boost":
                            newCapture.code = "boost";
                            break;
                        case "adidas":
                            newCapture.code = "adidas";
                            break;
                        default:
                            break;
                    }
                    newCapture.id = senderID;
                    newCapture.name = userName;
                    newCapture.score = parseFloat(arr[3].replace(')', ''));
                    newCapture.save(function (err, data) {
                        if (err) {
                            console.log(err);
                        }
                        console.log(newCapture);
                        shoe.findOne({'code': newCapture.code}, function (err, data) {
                            if (err) {
                                //Error servidor
                                response = {"error": true, "message": "Fetching error"};
                                res.status(500).json(response);
                            } else {
                                var randBegin = randomBegin[Math.floor(Math.random() * randomBegin.length)];
                                var response = randBegin + "\"" + data.name + "\"" + ". " + data.description
                                    + ". You have them for " + data.price + "$ at adidas.com";
                                sendTextMessage(senderID, response);
                            }
                        })
                    });
                    console.log(stdout);
                    console.log(stderr);
                });
                break;
            default:
                sendTextMessage(senderID, "I don't know about this...");
                break;
        }
    });

}

function processUrl(senderID, messageAttachments, userName){
    console.log(messageAttachments);
    var exec = require('child_process').exec;

    var cmd = 'python ../main.py ' + "\"" + messageAttachments + "\"";
    var newCapture = new capture();
    exec(cmd, function (error, stdout, stderr) {
        console.log("Error" + error);
        console.log("Stdout: " + stdout);
        var firstLine = stdout.split('\n')[0];
        console.log("First Line: " + firstLine);
        var arr = firstLine.split(" ");
        console.log("Arr: " + arr);
        switch (arr[0]) {
            case "bb1302":
                newCapture.code = "bb1302";
                break;
            case "zxflux":
                newCapture.code = "zxflux";
                break;
            case "c77124":
                newCapture.code = "c77124";
                break;
            case "ba8278":
                newCapture.code = "ba8278";
                break;
            case "bb0008":
                newCapture.code = "bb0008";
                break;
            case "bb5477":
                newCapture.code = "bb5477";
                break;
            case "boost":
                newCapture.code = "boost";
                break;
            case "adidas":
                newCapture.code = "adidas";
                break;
            case "invalid":
                newCapture.code = "invalid";
                break;
            default:
                break;
        }
        if (newCapture.code == "invalid") {
            sendTextMessage(senderID, "I don't know about this...");
        } else {
            newCapture.id = senderID;
            newCapture.name = userName;
            newCapture.score = parseFloat(arr[3].replace(')', ''));
            newCapture.save(function (err, data) {
                if (err) {
                    console.log(err);
                }
                console.log(newCapture);
                shoe.findOne({'code': newCapture.code}, function (err, data) {
                    if (err) {
                        //Error servidor
                        response = {"error": true, "message": "Fetching error"};
                        res.status(500).json(response);
                    } else {
                        var randBegin = randomBegin[Math.floor(Math.random() * randomBegin.length)];
                        var response = randBegin + "\"" + data.name + "\"" + ". " + data.description
                            + ". You have them for " + data.price + "$ at adidas.com";
                        sendTextMessage(senderID, response);
                    }
                })
            });
            console.log(stdout);
        }
    });
}

function sendGenericMessage(recipientId, messageText) {
    // To be expanded in later sections
}

function managePostBack(event){
    var senderID = event.sender.id;
    var recipientID = event.recipient.id;
    var timeOfPostback = event.timestamp;

    // The 'payload' param is a developer-defined field which is set in a postback
    // button for Structured Messages.
    var payload = event.postback.payload;

    console.log("Received postback for user %d and page %d with payload '%s' " +
        "at %d", senderID, recipientID, payload, timeOfPostback);

    // When a postback is called, we'll send a message back to the sender to
    // let them know it was successful
    sendTextMessage(senderID, JSON.parse(event.postback.payload).text);
}

function sendCardMessage(recipientId/*, trainer*/){
    var messageData = {
        recipient: {
            id: recipientId
        },
        message: {
            attachment: {
                type: "template",
                payload: {
                    template_type: "generic",
                    elements: [{
                        title: "ZAPATILLA X_PLR",
                        item_url: "http://www.adidas.es/zapatilla-x_plr/BB1100.html?pr=home_rr&slot=2",
                        image_url: "http://www.adidas.es/dis/dw/image/v2/aagl_prd/on/demandware.static/-/Sites-adidas-products/default/dw4863d725/zoom/BB1100_01_standard.jpg?sw=500&sfrm=jpg",
                        buttons: [{
                            type: "web_url",
                            url: "http://www.adidas.es/zapatilla-x_plr/BB1100.html?pr=home_rr&slot=2",
                            title: "Go to shop"
                        }, {
                            type: "postback",
                            title: "Show more info",
                            payload: '{ "name": "Zapatilla x_plr", "text": "jajajaja xddd"}'
                        }],
                    }]
                }
            }
        }/*
        message: {
            attachment: {
                type: "template",
                payload: {
                    template_type: "generic",
                    elements: [{
                        title: trainer.name,
                        item_url: trainer.itemUrl,
                        image_url: trainer.imageUrl,
                        buttons: [{
                            type: "web_url",
                            url: trainer.itemUrl,
                            title: "Go to shop"
                        }, {
                            type: "postback",
                            title: "Show more info",
                            payload: "Show more info",
                        }],
                    }, {
                        title: "touch",
                        subtitle: "Your Hands, Now in VR",
                        item_url: "https://www.oculus.com/en-us/touch/",
                        image_url: "http://messengerdemo.parseapp.com/img/touch.png",
                        buttons: [{
                            type: "web_url",
                            url: trainer.itemUrl,
                            title: "Open Web URL"
                        }, {
                            type: "postback",
                            title: "Call Postback",
                            payload: "Payload for second bubble",
                        }]
                    }]
                }
            }
        }*/
    };

    callSendAPI(messageData);
}

function sendTextMessage(recipientId, messageText) {
    console.log(messageText);
    var messageData = {
        recipient: {
            id: recipientId
        },
        message: {
            text: messageText
        }
    };

    callSendAPI(messageData);
}

function callSendAPI(messageData) {
    request({
        uri: 'https://graph.facebook.com/v2.6/me/messages',
        qs: { access_token: config.page_token },
        method: 'POST',
        json: messageData

    }, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            var recipientId = body.recipient_id;
            var messageId = body.message_id;

            console.log("Successfully sent generic message with id %s to recipient %s",
                messageId, recipientId);
        } else {
            console.error("Unable to send message.");
            console.error(response);
            console.error(error);
        }
    });
}

function sendLoading(senderID){
    request({
        uri: 'https://graph.facebook.com/v2.6/me/messages',
        qs: { access_token: config.page_token },
        method: 'POST',
        json: {"recipient": {"id": senderID},
            "sender_action":"typing_on"}
    });
}

function isUrl(url){
    var expression = /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi;
    var regex = new RegExp(expression);
    if (url.match(regex)) {
        return true;
    } else {
        return false;
    }
}

module.exports = router;
<|endoftext|>


<commit_before>'use strict'

const gulp = require('gulp')
const $ = require('gulp-load-plugins')()

const browserSync = require('browser-sync').create()
const runSequence = require('run-sequence')
const rimraf = require('rimraf')

let distTask = false

gulp.task('default', ['dev'])

gulp.task('dev', cb => {
  distTask = false
  runSequence(
    ['test', 'test:watch', 'styles:watch', 'templates:watch']
  )

  runSequence(
    ['clear'],
    ['scripts', 'styles', 'templates'],
    ['browser-sync']
    , cb)
})

gulp.task('dist', cb => {
  distTask = true

  runSequence(
    ['test', 'browser-sync']
  )

  runSequence(
    ['clear'],
    ['scripts', 'styles'],
    ['templates']
    , cb)
})

gulp.task('scripts', () => scripts('./app/scripts/app.js', './dist/scripts/', true))

gulp.task('templates', () => {
  const manifest = distTask ? require('./dist/rev-manifest.json') : ''

  return gulp.src('./app/index.html')
    .pipe($.if(distTask, $.revManifestReplace({
      base: '.',
      manifest: manifest
    })))
    .pipe($.if(distTask, $.htmlmin({
      removeComments: true,
      collapseWhitespace: true
    })))
    .pipe(gulp.dest('./dist'))
    .pipe(browserSync.stream())
})

gulp.task('templates:watch', () => {
  return gulp.watch('./app/index.html', ['templates'])
})

gulp.task('styles', () => {
  return gulp.src('./app/styles/styles.less')
    .pipe($.sourcemaps.init())
    .pipe($.less())
    .on('error', handleError)
    .pipe($.autoprefixer({browsers: ['last 2 versions', 'Firefox ESR', 'ie >= 9']}))
    .pipe($.if(distTask, $.minifyCss()))
    .pipe($.if(distTask, $.rev()))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('./dist/styles'))
    .pipe($.if(distTask, $.rev.manifest('dist/rev-manifest.json', {base: './dist', merge: true})))
    .pipe($.if(distTask, gulp.dest('./dist')))
    .pipe(browserSync.stream({match: '**/*.css'}))
})

gulp.task('styles:watch', () => {
  return gulp.watch('./app/styles/**', ['styles'])
})

gulp.task('test', () => {
  gulp.src('./test/**/*.js')
    .pipe($.ava())
    .on('error', handleError)
})

gulp.task('test:watch', () => {
  return gulp.watch(['./test/**/*.js', './app/scripts/**/*.js'], ['test'])
})

gulp.task('browser-sync', () => {
  browserSync.init({
    server: {
      baseDir: './dist'
    },
    ghostMode: false,
    port: 8080,
    open: false
  })
})

gulp.task('clear', cb => rimraf('./dist', cb))

// functions

const scripts = (from, to, watch) => {
  return gulp.src(from)
    .pipe($.webpack({
      watch: watch,
      devtool: 'source-map',
      output: { filename: from.split('/').reverse()[0] },
      module: {
        loaders: [{
          test: /\.js$/,
          exclude: /(node_modules|dist|test)/,
          loader: 'babel',
          query: { presets: ['es2015', 'stage-2'] }
        }]
      }
    }))
    .pipe(gulp.dest(to))
}

function handleError (err) {
  $.util.log($.util.colors.red(`Error: ${ err.message }`))
  // keeps gulp from hanging when error happens
  this.emit('end')
}
<commit_msg>gulpfile.js: refactor browser-sync task into function<commit_after>'use strict'

const gulp = require('gulp')
const $ = require('gulp-load-plugins')()

const browserSync = require('browser-sync').create()
const runSequence = require('run-sequence')
const rimraf = require('rimraf')

let distTask = false

gulp.task('default', ['dev'])

gulp.task('dev', cb => {
  distTask = false
  runSequence(
    ['test', 'test:watch', 'styles:watch', 'templates:watch']
  )

  runSequence(
    ['clear'],
    ['scripts', 'styles', 'templates'],
    ['browser-sync']
    , cb)
})

gulp.task('dist', cb => {
  distTask = true

  runSequence(
    ['test', 'browser-sync']
  )

  runSequence(
    ['clear'],
    ['scripts', 'styles'],
    ['templates']
    , cb)
})

gulp.task('clear', (cb) => rimraf('./dist', cb))
gulp.task('scripts', () => scripts('./app/scripts/app.js', './dist/scripts/', true))
gulp.task('server', () => server('./dist'))

gulp.task('templates', () => {
  const manifest = distTask ? require('./dist/rev-manifest.json') : ''

  return gulp.src('./app/index.html')
    .pipe($.if(distTask, $.revManifestReplace({
      base: '.',
      manifest: manifest
    })))
    .pipe($.if(distTask, $.htmlmin({
      removeComments: true,
      collapseWhitespace: true
    })))
    .pipe(gulp.dest('./dist'))
    .pipe(browserSync.stream())
})

gulp.task('templates:watch', () => {
  return gulp.watch('./app/index.html', ['templates'])
})

gulp.task('styles', () => {
  return gulp.src('./app/styles/styles.less')
    .pipe($.sourcemaps.init())
    .pipe($.less())
    .on('error', handleError)
    .pipe($.autoprefixer({browsers: ['last 2 versions', 'Firefox ESR', 'ie >= 9']}))
    .pipe($.if(distTask, $.minifyCss()))
    .pipe($.if(distTask, $.rev()))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('./dist/styles'))
    .pipe($.if(distTask, $.rev.manifest('dist/rev-manifest.json', {base: './dist', merge: true})))
    .pipe($.if(distTask, gulp.dest('./dist')))
    .pipe(browserSync.stream({match: '**/*.css'}))
})

gulp.task('styles:watch', () => {
  return gulp.watch('./app/styles/**', ['styles'])
})

gulp.task('test', () => {
  gulp.src('./test/**/*.js')
    .pipe($.ava())
    .on('error', handleError)
})

gulp.task('test:watch', () => {
  return gulp.watch(['./test/**/*.js', './app/scripts/**/*.js'], ['test'])
})

// functions

const server = (baseDir) => {
  browserSync.init({
    server: {
      baseDir: baseDir
    },
    ghostMode: false,
    port: 8080,
    open: false
  })
}

const scripts = (from, to, watch) => {
  return gulp.src(from)
    .pipe($.webpack({
      watch: watch,
      devtool: 'source-map',
      output: { filename: from.split('/').reverse()[0] },
      module: {
        loaders: [{
          test: /\.js$/,
          exclude: /(node_modules|dist|test)/,
          loader: 'babel',
          query: { presets: ['es2015', 'stage-2'] }
        }]
      }
    }))
    .pipe(gulp.dest(to))
}

function handleError (err) {
  $.util.log($.util.colors.red(`Error: ${ err.message }`))
  // keeps gulp from hanging when error happens
  this.emit('end')
}
<|endoftext|>