<commit_before>/* routes/system.js
 * Copyright 2014 Sergei Ianovich
 *
 * Licensed under AGPL-3.0 or later, see LICENSE
 * Process Control Service Web Interface
 */

var System = require('../models/system');
var Device = require('../models/device');
var auth = require('./_auth');
var perPage = 25;

module.exports.load = function (req, res, next, id) {
  System.findOne({ _id: id }, function (err, system) {
    req.system = system;
    next();
  })
}

function requireAdmin(req, res, next) {
  if (req.operator.admin)
    return next();
  res.send(401);
}

var exportFields = '_id device site name outputs setpoints';

function showSystem(req, res) {
  if (!req.system)
    return res.send(404);
  var system = {};
  exportFields.split(' ').forEach(function (f) {
    system[f] = req.system[f];
  });
  res.json_ng(system);
}

function showSetpoints(req, res) {
  if (!req.device)
    return res.send(404);
  System.find({ 'device': req.device._id })
    .exec(function (err, systems) {
      if (err) {
        return res.json(500, err);
      }
      var setpoints = {};
      systems.forEach(function (system) {
        if (system.setpoints) {
          Object.keys(system.setpoints).forEach(function (s) {
            if (system.setpoints.hasOwnProperty(s)) {
              setpoints[s] = system.setpoints[s];
            }
          });
        }
      });
      res.json(setpoints);
    });
}

var systemFields = ['name', 'device', 'outputs', 'setpoints'];

function updateSetpoints(req, res) {
  var dirty = false;
  var bad = false;
  Object.keys(req.system.setpoints).forEach(function (s) {
    if (typeof req.body.setpoints[s] != 'string' &&
      typeof req.body.setpoints[s] != 'number') {
      console.log(typeof req.body.setpoints[s]);
      bad = true;
      return;
    }
    if (req.system.setpoints[s] != req.body.setpoints[s]) {
      dirty = true;
      req.system.setpoints[s] = req.body.setpoints[s];
      req.system.markModified('setpoints.'+s);
    }
  });
  if (!dirty) return res.send(500, 'Unchanged');
  if (!bad) return res.send(500, 'Malformed');
  req.system.save(function (err) {
    if (err) {
      return res.json(500, err);
    }
    res.json_ng(req.system);
  });
}

function updateSystem(req, res) {
  if (!req.system)
    return res.send(500);
  if (!req.operator.admin) return updateSetpoints(req, res);
  systemFields.forEach(function (f) {
    req.system[f] = req.body[f];
  });
  req.system.save(function (err) {
    if (err) {
      return res.json(500, err);
    }
    res.json_ng(req.system);
  });
}

function indexSystems(req, res) {
  if (!req.site)
    return res.send(404);
  var page = Number(req.query.page) || 1;
  page--;
  if (page < 0)
    page = 0;
  System.find({site: req.site._id}).count(function (err, count) {
    if (err)
      return res.send(500, err.toString());
    if ((page * perPage) > count)
      page = Math.floor((count - 1) / perPage);
    System
    .find({site: req.site._id}, exportFields)
    .sort({ name: 1 })
    .skip(page*perPage)
    .limit(perPage)
    .exec(function (err, systems) {
      if (err)
        return res.send(500, err.toString());
      systems.push({ count: count });
      res.json_ng(systems);
    });
  });
}

function createSystem(req, res) {
  if (!req.site)
    return res.send(500);
  req.system = new System();
  req.system.site = req.site._id;
  systemFields.forEach(function (f) {
    req.system[f] = req.body[f];
  });
  req.system.save(function (err) {
    if (err) {
      return res.json(500, err);
    }
    res.json(req.system);
  });
}

module.exports.show = [ auth.authenticate,
                        showSystem];

module.exports.setpoints = [ showSetpoints ];

module.exports.update = [ auth.authenticate,
                          updateSystem];

module.exports.index = [ auth.authenticate,
                         indexSystems];

module.exports.create = [ auth.authenticate,
                          requireAdmin,
                          createSystem];

// vim:ts=2 sts=2 sw=2 et:
<commit_msg>system: fix setpoints update<commit_after>/* routes/system.js
 * Copyright 2014 Sergei Ianovich
 *
 * Licensed under AGPL-3.0 or later, see LICENSE
 * Process Control Service Web Interface
 */

var System = require('../models/system');
var Device = require('../models/device');
var auth = require('./_auth');
var perPage = 25;

module.exports.load = function (req, res, next, id) {
  System.findOne({ _id: id }, function (err, system) {
    req.system = system;
    next();
  })
}

function requireAdmin(req, res, next) {
  if (req.operator.admin)
    return next();
  res.send(401);
}

var exportFields = '_id device site name outputs setpoints';

function showSystem(req, res) {
  if (!req.system)
    return res.send(404);
  var system = {};
  exportFields.split(' ').forEach(function (f) {
    system[f] = req.system[f];
  });
  res.json_ng(system);
}

function showSetpoints(req, res) {
  if (!req.device)
    return res.send(404);
  System.find({ 'device': req.device._id })
    .exec(function (err, systems) {
      if (err) {
        return res.json(500, err);
      }
      var setpoints = {};
      systems.forEach(function (system) {
        if (system.setpoints) {
          Object.keys(system.setpoints).forEach(function (s) {
            if (system.setpoints.hasOwnProperty(s)) {
              setpoints[s] = system.setpoints[s];
            }
          });
        }
      });
      res.json(setpoints);
    });
}

var systemFields = ['name', 'device', 'outputs', 'setpoints'];

function updateSetpoints(req, res) {
  var dirty = false;
  var bad = false;
  Object.keys(req.system.setpoints).forEach(function (s) {
    if (typeof req.body.setpoints[s] != 'string' &&
      typeof req.body.setpoints[s] != 'number') {
      console.log(typeof req.body.setpoints[s]);
      bad = true;
      return;
    }
    if (req.system.setpoints[s] != req.body.setpoints[s]) {
      dirty = true;
      req.system.setpoints[s] = req.body.setpoints[s];
      req.system.markModified('setpoints.'+s);
    }
  });
  if (!dirty) return res.send(500, 'Unchanged');
  if (bad) return res.send(500, 'Malformed');
  req.system.save(function (err) {
    if (err) {
      return res.json(500, err);
    }
    res.json_ng(req.system);
  });
}

function updateSystem(req, res) {
  if (!req.system)
    return res.send(500);
  if (!req.operator.admin) return updateSetpoints(req, res);
  systemFields.forEach(function (f) {
    req.system[f] = req.body[f];
  });
  req.system.save(function (err) {
    if (err) {
      return res.json(500, err);
    }
    res.json_ng(req.system);
  });
}

function indexSystems(req, res) {
  if (!req.site)
    return res.send(404);
  var page = Number(req.query.page) || 1;
  page--;
  if (page < 0)
    page = 0;
  System.find({site: req.site._id}).count(function (err, count) {
    if (err)
      return res.send(500, err.toString());
    if ((page * perPage) > count)
      page = Math.floor((count - 1) / perPage);
    System
    .find({site: req.site._id}, exportFields)
    .sort({ name: 1 })
    .skip(page*perPage)
    .limit(perPage)
    .exec(function (err, systems) {
      if (err)
        return res.send(500, err.toString());
      systems.push({ count: count });
      res.json_ng(systems);
    });
  });
}

function createSystem(req, res) {
  if (!req.site)
    return res.send(500);
  req.system = new System();
  req.system.site = req.site._id;
  systemFields.forEach(function (f) {
    req.system[f] = req.body[f];
  });
  req.system.save(function (err) {
    if (err) {
      return res.json(500, err);
    }
    res.json(req.system);
  });
}

module.exports.show = [ auth.authenticate,
                        showSystem];

module.exports.setpoints = [ showSetpoints ];

module.exports.update = [ auth.authenticate,
                          updateSystem];

module.exports.index = [ auth.authenticate,
                         indexSystems];

module.exports.create = [ auth.authenticate,
                          requireAdmin,
                          createSystem];

// vim:ts=2 sts=2 sw=2 et:
<|endoftext|>


<commit_before>'use strict';

var sass = require('node-sass'),
    hbs = require('handlebars'),
    path = require('path'),
    fs = require('fs'),
    yaml = require('js-yaml'),
    _ = require('lodash'),
    rsvp = require('rsvp');

function findFiles(manifest, type, themeDir) {
  var templates = _(manifest[type]).map(function(filename) {
    var filename = filename.split('.').shift();
    return new rsvp.Promise(function(resolve, reject) {
      fs.readFile(path.join(themeDir, filename + '.hbs'), { encoding: 'utf8' }, function(err, data) {
        if (err) {
          var alt = filename + '.handlebars';
          fs.readFile(path.join(themeDir, alt), { encoding: 'utf8' }, function(err, data) {
            if (err) {
              reject(err);
            } else {
              resolve({ name: filename, type: type, content: data });
            }
          });
        } else {
          resolve({ name: filename, type: type, content: data });
        }
      });
    });
  }).value();
  return rsvp.all(templates);
}

function wrapTemplates(templates) {
  var js = "(function() { var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; partials = Handlebars.partials = Handlebars.partials || {};";
  _(templates).each(function(template) {
    js = js + template.type + '["' + template.name + '"] = template(' + template.content + ');'
  });
  js = js + '})();';
  return js;
}

exports.preview = function(req, res){
  res.render('themes/preview', { theme: req.params.theme });
};

exports.asset = function(req, res){
  var themeDir = path.join(process.cwd(), req.params.theme),
      filename = req.params.file,
      filepath = path.join(themeDir, filename);

  res.set('Cache-Control', 'no-cache, no-store, must-revalidate');
  res.set('Expires', 0);
  res.set('Content-Type', 'text/css');

  if (filename.split('.').pop() === 'css') {
    fs.exists(filepath, function(exists) {
      if (exists) {
        res.sendfile(filepath);
      } else {
        sass.render({
          file: filepath.replace(/\.css$/, '.scss'),
          success: function(css) { res.send(css); },
          error: function(error) { console.log(error); }
        });
      }
    });
  } else {
    res.sendfile(filepath);
  }
};

exports.theme = function(req, res){
  var themeDir = path.join(process.cwd(), req.params.theme),
      manifestPath = path.join(themeDir, 'manifest.yml'),
      files,
      manifest;

  manifest = yaml.safeLoad(fs.readFileSync(manifestPath, {encoding: 'utf8'}));

  files = {
    templates: findFiles(manifest, 'templates', themeDir),
    partials: findFiles(manifest, 'partials', themeDir)
  }

  rsvp.hash(files).then(function(results) {
    results = results.templates.concat(results.partials);
    _(results).each(function(template) {
      template.content = hbs.precompile(template.content);
    });
    res.set('Content-Type', 'application/javascript');
    res.set('Cache-Control', 'no-cache, no-store, must-revalidate');
    res.set('Expires', 0);
    res.send(wrapTemplates(results));
  }).catch(function(err) { throw err; });

};
<commit_msg>don't set text/css content type for images<commit_after>'use strict';

var sass = require('node-sass'),
    hbs = require('handlebars'),
    path = require('path'),
    fs = require('fs'),
    yaml = require('js-yaml'),
    _ = require('lodash'),
    rsvp = require('rsvp');

function findFiles(manifest, type, themeDir) {
  var templates = _(manifest[type]).map(function(filename) {
    var filename = filename.split('.').shift();
    return new rsvp.Promise(function(resolve, reject) {
      fs.readFile(path.join(themeDir, filename + '.hbs'), { encoding: 'utf8' }, function(err, data) {
        if (err) {
          var alt = filename + '.handlebars';
          fs.readFile(path.join(themeDir, alt), { encoding: 'utf8' }, function(err, data) {
            if (err) {
              reject(err);
            } else {
              resolve({ name: filename, type: type, content: data });
            }
          });
        } else {
          resolve({ name: filename, type: type, content: data });
        }
      });
    });
  }).value();
  return rsvp.all(templates);
}

function wrapTemplates(templates) {
  var js = "(function() { var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; partials = Handlebars.partials = Handlebars.partials || {};";
  _(templates).each(function(template) {
    js = js + template.type + '["' + template.name + '"] = template(' + template.content + ');'
  });
  js = js + '})();';
  return js;
}

exports.preview = function(req, res){
  res.render('themes/preview', { theme: req.params.theme });
};

exports.asset = function(req, res){
  var themeDir = path.join(process.cwd(), req.params.theme),
      filename = req.params.file,
      filepath = path.join(themeDir, filename);

  res.set('Cache-Control', 'no-cache, no-store, must-revalidate');
  res.set('Expires', 0);

  if (filename.split('.').pop() === 'css') {
    res.set('Content-Type', 'text/css');
    fs.exists(filepath, function(exists) {
      if (exists) {
        res.sendfile(filepath);
      } else {
        sass.render({
          file: filepath.replace(/\.css$/, '.scss'),
          success: function(css) { res.send(css); },
          error: function(error) { console.log(error); }
        });
      }
    });
  } else {
    res.sendfile(filepath);
  }
};

exports.theme = function(req, res){
  var themeDir = path.join(process.cwd(), req.params.theme),
      manifestPath = path.join(themeDir, 'manifest.yml'),
      files,
      manifest;

  manifest = yaml.safeLoad(fs.readFileSync(manifestPath, {encoding: 'utf8'}));

  files = {
    templates: findFiles(manifest, 'templates', themeDir),
    partials: findFiles(manifest, 'partials', themeDir)
  }

  rsvp.hash(files).then(function(results) {
    results = results.templates.concat(results.partials);
    _(results).each(function(template) {
      template.content = hbs.precompile(template.content);
    });
    res.set('Content-Type', 'application/javascript');
    res.set('Cache-Control', 'no-cache, no-store, must-revalidate');
    res.set('Expires', 0);
    res.send(wrapTemplates(results));
  }).catch(function(err) { throw err; });

};
<|endoftext|>


<commit_before>const utils = require('../lib/utils')
const insecurity = require('../lib/insecurity')
const jwt = require('jsonwebtoken')
const models = require('../models/index')
const cache = require('../data/datacache')
const Op = models.Sequelize.Op
const challenges = cache.challenges
const products = cache.products

exports.forgedFeedbackChallenge = () => (req, res, next) => {
  /* jshint eqeqeq:false */
  if (utils.notSolved(challenges.forgedFeedbackChallenge)) {
    const user = insecurity.authenticatedUsers.from(req)
    const userId = user && user.data ? user.data.id : undefined
    if (req.body.UserId && req.body.UserId && req.body.UserId != userId) { // eslint-disable-line eqeqeq
      utils.solve(challenges.forgedFeedbackChallenge)
    }
  }
  next()
}

exports.accessControlChallenges = () => (req, res, next) => {
  if (utils.notSolved(challenges.scoreBoardChallenge) && utils.endsWith(req.url, '/scoreboard.png')) {
    utils.solve(challenges.scoreBoardChallenge)
  } else if (utils.notSolved(challenges.adminSectionChallenge) && utils.endsWith(req.url, '/administration.png')) {
    utils.solve(challenges.adminSectionChallenge)
  } else if (utils.notSolved(challenges.geocitiesThemeChallenge) && utils.endsWith(req.url, '/microfab.gif')) {
    utils.solve(challenges.geocitiesThemeChallenge)
  } else if (utils.notSolved(challenges.extraLanguageChallenge) && utils.endsWith(req.url, '/tlh.json')) {
    utils.solve(challenges.extraLanguageChallenge)
  } else if (utils.notSolved(challenges.retrieveBlueprintChallenge) && utils.endsWith(req.url, cache.retrieveBlueprintChallengeFile)) {
    utils.solve(challenges.retrieveBlueprintChallenge)
  }
  next()
}

exports.errorHandlingChallenge = () => (err, req, res, next) => {
  if (utils.notSolved(challenges.errorHandlingChallenge) && err && (res.statusCode === 200 || res.statusCode > 401)) {
    utils.solve(challenges.errorHandlingChallenge)
  }
  next(err)
}

exports.jwtChallenges = () => (req, res, next) => {
  if (utils.notSolved(challenges.jwtTier1Challenge) || utils.notSolved(challenges.jwtTier2Challenge)) {
    const decoded = jwt.decode(utils.jwtFrom(req), { complete: true, json: true })
    const payload = decoded ? decoded.payload : {}
    const header = decoded ? decoded.header : {}
    if (utils.notSolved(challenges.jwtTier1Challenge)) {
      if (header.alg === 'none' && payload.data && payload.data.email && payload.data.email.match(/jwtn3d@/)) {
        utils.solve(challenges.jwtTier1Challenge)
      }
    }
    if (utils.notSolved(challenges.jwtTier2Challenge)) {
      if (header.alg === 'HS256' && payload.data && payload.data.email && payload.data.email.match(/rsa_lord@/)) {
        utils.solve(challenges.jwtTier2Challenge)
      }
    }
  }
  next()
}

exports.databaseRelatedChallenges = () => (req, res, next) => {
  if (utils.notSolved(challenges.changeProductChallenge) && products.osaft) {
    products.osaft.reload().then(() => {
      if (!utils.contains(products.osaft.description, 'https://www.owasp.org/index.php/O-Saft')) {
        if (utils.contains(products.osaft.description, 'More...')) {
          utils.solve(challenges.changeProductChallenge)
        }
      }
    })
  }
  if (utils.notSolved(challenges.feedbackChallenge)) {
    models.Feedback.findAndCountAll({ where: { rating: 5 } }).then(feedbacks => {
      if (feedbacks.count === 0) {
        utils.solve(challenges.feedbackChallenge)
      }
    })
  }
  if (utils.notSolved(challenges.knownVulnerableComponentChallenge)) {
    models.Feedback.findAndCountAll({
      where: {
        comment: {
          [Op.or]: [
            {[Op.and]: [
              {[Op.like]: '%sanitize-html%'},
              {[Op.like]: '%1.4.2%'}
            ]},
            {[Op.and]: [
              {[Op.like]: '%express-jwt%'},
              {[Op.like]: '%0.1.3%'}
            ]}
          ]
        }
      }
    }).then(data => {
      if (data.count > 0) {
        utils.solve(challenges.knownVulnerableComponentChallenge)
      }
    })
  }
  if (utils.notSolved(challenges.weirdCryptoChallenge)) {
    models.Feedback.findAndCountAll({
      where: {
        comment: {
          [Op.or]: [
              {[Op.like]: '%z85%'},
              {[Op.like]: '%base85%'},
              {[Op.like]: '%hashids%'},
              {[Op.like]: '%md5%'},
              {[Op.like]: '%base64%'}
          ]
        }
      }
    }).then(data => {
      if (data.count > 0) {
        utils.solve(challenges.weirdCryptoChallenge)
      }
    })
  }
  if (utils.notSolved(challenges.typosquattingNpmChallenge)) {
    models.Feedback.findAndCountAll({ where: { comment: { [Op.like]: '%epilogue-js%' } } }
    ).then(data => {
      if (data.count > 0) {
        utils.solve(challenges.typosquattingNpmChallenge)
      }
    })
  }
  if (utils.notSolved(challenges.typosquattingBowerChallenge)) {
    models.Feedback.findAndCountAll({ where: { comment: { [Op.like]: '%angular-tooltipp%' } } }
    ).then(data => {
      if (data.count > 0) {
        utils.solve(challenges.typosquattingBowerChallenge)
      }
    })
  }
  next()
}
<commit_msg>Accept feedback-triggered challenges also via complaints (resolves #383)<commit_after>const utils = require('../lib/utils')
const insecurity = require('../lib/insecurity')
const jwt = require('jsonwebtoken')
const models = require('../models/index')
const cache = require('../data/datacache')
const Op = models.Sequelize.Op
const challenges = cache.challenges
const products = cache.products

exports.forgedFeedbackChallenge = () => (req, res, next) => {
  /* jshint eqeqeq:false */
  if (utils.notSolved(challenges.forgedFeedbackChallenge)) {
    const user = insecurity.authenticatedUsers.from(req)
    const userId = user && user.data ? user.data.id : undefined
    if (req.body.UserId && req.body.UserId && req.body.UserId != userId) { // eslint-disable-line eqeqeq
      utils.solve(challenges.forgedFeedbackChallenge)
    }
  }
  next()
}

exports.accessControlChallenges = () => (req, res, next) => {
  if (utils.notSolved(challenges.scoreBoardChallenge) && utils.endsWith(req.url, '/scoreboard.png')) {
    utils.solve(challenges.scoreBoardChallenge)
  } else if (utils.notSolved(challenges.adminSectionChallenge) && utils.endsWith(req.url, '/administration.png')) {
    utils.solve(challenges.adminSectionChallenge)
  } else if (utils.notSolved(challenges.geocitiesThemeChallenge) && utils.endsWith(req.url, '/microfab.gif')) {
    utils.solve(challenges.geocitiesThemeChallenge)
  } else if (utils.notSolved(challenges.extraLanguageChallenge) && utils.endsWith(req.url, '/tlh.json')) {
    utils.solve(challenges.extraLanguageChallenge)
  } else if (utils.notSolved(challenges.retrieveBlueprintChallenge) && utils.endsWith(req.url, cache.retrieveBlueprintChallengeFile)) {
    utils.solve(challenges.retrieveBlueprintChallenge)
  }
  next()
}

exports.errorHandlingChallenge = () => (err, req, res, next) => {
  if (utils.notSolved(challenges.errorHandlingChallenge) && err && (res.statusCode === 200 || res.statusCode > 401)) {
    utils.solve(challenges.errorHandlingChallenge)
  }
  next(err)
}

exports.jwtChallenges = () => (req, res, next) => {
  if (utils.notSolved(challenges.jwtTier1Challenge) || utils.notSolved(challenges.jwtTier2Challenge)) {
    const decoded = jwt.decode(utils.jwtFrom(req), { complete: true, json: true })
    const payload = decoded ? decoded.payload : {}
    const header = decoded ? decoded.header : {}
    if (utils.notSolved(challenges.jwtTier1Challenge)) {
      if (header.alg === 'none' && payload.data && payload.data.email && payload.data.email.match(/jwtn3d@/)) {
        utils.solve(challenges.jwtTier1Challenge)
      }
    }
    if (utils.notSolved(challenges.jwtTier2Challenge)) {
      if (header.alg === 'HS256' && payload.data && payload.data.email && payload.data.email.match(/rsa_lord@/)) {
        utils.solve(challenges.jwtTier2Challenge)
      }
    }
  }
  next()
}

exports.databaseRelatedChallenges = () => (req, res, next) => {
  if (utils.notSolved(challenges.changeProductChallenge) && products.osaft) {
    products.osaft.reload().then(() => {
      if (!utils.contains(products.osaft.description, 'https://www.owasp.org/index.php/O-Saft')) {
        if (utils.contains(products.osaft.description, 'More...')) {
          utils.solve(challenges.changeProductChallenge)
        }
      }
    })
  }
  if (utils.notSolved(challenges.feedbackChallenge)) {
    models.Feedback.findAndCountAll({ where: { rating: 5 } }).then(feedbacks => {
      if (feedbacks.count === 0) {
        utils.solve(challenges.feedbackChallenge)
      }
    })
  }
  if (utils.notSolved(challenges.knownVulnerableComponentChallenge)) {
    let knownVulnerableComponents = [
      {[Op.and]: [
        {[Op.like]: '%sanitize-html%'},
        {[Op.like]: '%1.4.2%'}
      ]},
      {[Op.and]: [
        {[Op.like]: '%express-jwt%'},
        {[Op.like]: '%0.1.3%'}
      ]}
    ]
    models.Feedback.findAndCountAll({
      where: {
        comment: {
          [Op.or]: knownVulnerableComponents
        }
      }
    }).then(data => {
      if (data.count > 0) {
        utils.solve(challenges.knownVulnerableComponentChallenge)
      }
    })
    models.Complaint.findAndCountAll({
      where: {
        message: {
          [Op.or]: knownVulnerableComponents
        }
      }
    }).then(data => {
      if (data.count > 0) {
        utils.solve(challenges.knownVulnerableComponentChallenge)
      }
    })
  }
  if (utils.notSolved(challenges.weirdCryptoChallenge)) {
    let weirdCryptos = [
      {[Op.like]: '%z85%'},
      {[Op.like]: '%base85%'},
      {[Op.like]: '%hashids%'},
      {[Op.like]: '%md5%'},
      {[Op.like]: '%base64%'}
    ]
    models.Feedback.findAndCountAll({
      where: {
        comment: {
          [Op.or]: weirdCryptos
        }
      }
    }).then(data => {
      if (data.count > 0) {
        utils.solve(challenges.weirdCryptoChallenge)
      }
    })
    models.Complaint.findAndCountAll({
      where: {
        message: {
          [Op.or]: weirdCryptos
        }
      }
    }).then(data => {
      if (data.count > 0) {
        utils.solve(challenges.weirdCryptoChallenge)
      }
    })
  }
  if (utils.notSolved(challenges.typosquattingNpmChallenge)) {
    models.Feedback.findAndCountAll({ where: { comment: { [Op.like]: '%epilogue-js%' } } }
    ).then(data => {
      if (data.count > 0) {
        utils.solve(challenges.typosquattingNpmChallenge)
      }
    })
    models.Complaint.findAndCountAll({ where: { message: { [Op.like]: '%epilogue-js%' } } }
    ).then(data => {
      if (data.count > 0) {
        utils.solve(challenges.typosquattingNpmChallenge)
      }
    })
  }
  if (utils.notSolved(challenges.typosquattingBowerChallenge)) {
    models.Feedback.findAndCountAll({ where: { comment: { [Op.like]: '%angular-tooltipp%' } } }
    ).then(data => {
      if (data.count > 0) {
        utils.solve(challenges.typosquattingBowerChallenge)
      }
    })
    models.Complaint.findAndCountAll({ where: { message: { [Op.like]: '%angular-tooltipp%' } } }
    ).then(data => {
      if (data.count > 0) {
        utils.solve(challenges.typosquattingBowerChallenge)
      }
    })
  }
  next()
}
<|endoftext|>


<commit_before>'use strict'

process.env.DEBUG = 'bfx:examples:*'

const _flatten = require('lodash/flatten')
const debug = require('debug')('bfx:examples:ws2-manager')
const bfx = require('./bfx')

const Manager = require('../lib/ws2_manager')
const rest = bfx.rest(2, { transform: true })

debug('fetching symbol details...')

rest.symbolDetails().then(details => {
  const symbols = details.map(d => `t${d.pair.toUpperCase()}`)
  const timeFrames = ['1m', '5m', '30m', '1h', '6h']
  const keys = _flatten(symbols.map(s => {
    return timeFrames.map(tf => `trade:${tf}:${s}`)
  }))

  const m = new Manager({
    transform: true,
    url: bfx.args.wsURL,
    ...bfx.args
  })

  m.on('error', (err) => {
    debug('error: %s', err)
  })

  m.once('open', () => {
    debug('open')

    keys.forEach(key => {
      m.subscribeCandles(key)

      m.onCandle({ key }, (candles) => {
        debug('recv %d candles on channel %s', candles.length, key)
      })
    })

    setTimeout(() => {
      debug('num keys: %d', keys.length)
      debug('num sockets: %d', m.getNumSockets())
      debug('socket info: %j', m.getSocketInfo())
    }, 6000)
  })

  m.openSocket()
})
<commit_msg>(feature) sub to all relevant data channels in channel example<commit_after>'use strict'

process.env.DEBUG = 'bfx:examples:*'

const _flatten = require('lodash/flatten')
const debug = require('debug')('bfx:examples:ws2-manager')
const bfx = require('./bfx')

const Manager = require('../lib/ws2_manager')
const rest = bfx.rest(2, { transform: true })

debug('fetching symbol details...')

rest.symbolDetails().then(details => {
  const symbols = details.map(d => `t${d.pair.toUpperCase()}`)
  const timeFrames = ['1m', '5m', '30m', '1h', '6h']
  const keys = _flatten(symbols.map(s => {
    return timeFrames.map(tf => `trade:${tf}:${s}`)
  }))

  const m = new Manager({
    url: bfx.args.wsURL,
    ...bfx.args
  })

  m.on('error', (err) => {
    debug('error: %s', err)
  })

  m.once('open', () => {
    debug('open')

    keys.forEach(key => {
      m.subscribeCandles(key)
      m.onCandle({ key }, (candles) => {
        debug('recv %d candles on channel %s', candles.length, key)
      })
    })

    symbols.forEach(symbol => {
      m.subscribeTrades(symbol)
      m.onTrades({ symbol }, (trades) => {
        debug('recv %d trades on channel %s', trades.length, symbol)
      })
    })

    symbols.forEach(symbol => {
      m.subscribeTicker(symbol)
      m.onTicker({ symbol }, (ticker) => {
        debug('recv ticker on channel %s: %j', symbol, ticker)
      })
    })

    symbols.forEach(symbol => {
      m.subscribeOrderBook(symbol)
      m.onOrderBook({ symbol }, (update) => {
        debug('recv book update on channel %s: %j', symbol, update)
      })
    })

    setInterval(() => {
      debug('num keys: %d', keys.length)
      debug('num sockets: %d', m.getNumSockets())
      debug('socket info: %j', m.getSocketInfo())
    }, 5000)
  })

  m.openSocket()
})
<|endoftext|>


<commit_before>const React = require('react');
const ReactNative = require('react-native');
const {
  View,
  Animated,
  StyleSheet,
  ScrollView,
  TouchableOpacity,
  Text,
  Platform,
  findNodeHandle,
  Dimensions,
} = ReactNative;

const TAB_HEIGHT = 50;
const WINDOW_WIDTH = Dimensions.get('window').width;

const ScrollableTabBar = React.createClass({
  propTypes: {
    goToPage: React.PropTypes.func,
    activeTab: React.PropTypes.number,
    tabs: React.PropTypes.array,
    underlineColor: React.PropTypes.string,
    underlineHeight: React.PropTypes.number,
    backgroundColor: React.PropTypes.string,
    activeTextColor: React.PropTypes.string,
    inactiveTextColor: React.PropTypes.string,
    scrollOffset: React.PropTypes.number,
    style: View.propTypes.style,
    tabStyle: View.propTypes.style,
    tabsContainerStyle: View.propTypes.style,
  },

  getDefaultProps() {
    return {
      scrollOffset: 52,
      activeTextColor: 'navy',
      inactiveTextColor: 'black',
      underlineColor: 'navy',
      backgroundColor: null,
      underlineHeight: 4,
      style: {},
      tabStyle: {},
      tabsContainerStyle: {},
    };
  },

  getInitialState() {
    this._tabsMeasurements = [];
    return {
      _leftTabUnderline: new Animated.Value(0),
      _widthTabUnderline: new Animated.Value(0),
      _containerWidth: null,
    };
  },

  componentDidMount() {
    this.props.scrollValue.addListener(this.updateView);
  },

  updateView(offset) {
    const position = Math.floor(offset.value);
    const pageOffset = offset.value % 1;
    const tabCount = this.props.tabs.length;

    if (tabCount === 0 || offset.value < 0 || offset.value > tabCount - 1) {
      return;
    }

    if (this.necessarilyMeasurementsCompleted(position)) {
      this.updateTabPanel(position, pageOffset);
      this.updateTabUnderline(position, pageOffset, tabCount);
    }
  },

  necessarilyMeasurementsCompleted(position) {
    return this._tabsMeasurements[position] && this._tabsMeasurements[position + 1];
  },

  updateTabPanel(position, pageOffset) {
    const absolutePageOffset = pageOffset * this._tabsMeasurements[position].width;
    let newScrollX = this._tabsMeasurements[position].left + absolutePageOffset;

    newScrollX -= this.props.scrollOffset;
    newScrollX = newScrollX >= 0 ? newScrollX : 0;

    if (Platform === 'android') {
      this._scrollView.scrollTo({x: newScrollX, y: 0, });
    } else {
      const rightBoundScroll = this._tabContainerMeasurements.width - (this._containerMeasurements.width);
      newScrollX = newScrollX > rightBoundScroll ? rightBoundScroll : newScrollX;
      this._scrollView.scrollTo({x: newScrollX, y: 0, });
    }

  },

  updateTabUnderline(position, pageOffset, tabCount) {
    const lineLeft = this._tabsMeasurements[position].left;
    const lineRight = this._tabsMeasurements[position].right;

    if (position < tabCount - 1) {
      const nextTabLeft = this._tabsMeasurements[position + 1].left;
      const nextTabRight = this._tabsMeasurements[position + 1].right;

      const newLineLeft = (pageOffset * nextTabLeft + (1 - pageOffset) * lineLeft);
      const newLineRight = (pageOffset * nextTabRight + (1 - pageOffset) * lineRight);

      this.state._leftTabUnderline.setValue(newLineLeft);
      this.state._widthTabUnderline.setValue(newLineRight - newLineLeft);
    } else {
      this.state._leftTabUnderline.setValue(lineLeft);
      this.state._widthTabUnderline.setValue(lineRight - lineLeft);
    }
  },

  renderTabOption(name, page) {
    const isTabActive = this.props.activeTab === page;
    const { activeTextColor, inactiveTextColor, textStyle, } = this.props;
    const textColor = isTabActive ? activeTextColor : inactiveTextColor;
    const fontWeight = isTabActive ? 'bold' : 'normal';

    return <TouchableOpacity
      key={name}
      ref={'tab_' + page}
      accessible={true}
      accessibilityLabel={name}
      accessibilityTraits='button'
      style={[styles.tab, this.props.tabStyle]}
      onPress={() => this.props.goToPage(page)}
      onLayout={this.measureTab.bind(this, page)}
    >
      <View>
        <Text style={[{color: textColor, fontWeight, }, textStyle, ]}>
          {name}
        </Text>
      </View>
    </TouchableOpacity>;
  },

  measureTab(page) {
    const tabContainerhandle = findNodeHandle(this.refs.tabContainer);
    this.refs['tab_' + page].measureLayout(tabContainerhandle, (ox, oy, width, height, pageX, pageY) => {
      this._tabsMeasurements[page] = {left: ox, right: ox + width, width: width, height: height, };

      this.updateView({value: this.props.scrollValue._value, });
    });
  },

  render() {
    const tabUnderlineStyle = {
      position: 'absolute',
      height: this.props.underlineHeight,
      backgroundColor: this.props.underlineColor,
      bottom: 0,
    };

    const dynamicTabUnderline = {
      left: this.state._leftTabUnderline,
      width: this.state._widthTabUnderline,
    };

    return  <View
      style={[styles.container, {backgroundColor: this.props.backgroundColor, }, this.props.style]}
      onLayout={this.onContainerLayout}
    >
      <ScrollView
        ref={(scrollView) => { this._scrollView = scrollView; }}
        horizontal={true}
        showsHorizontalScrollIndicator={false}
        showsVerticalScrollIndicator={false}
        style={styles.scrollableContainer}
        directionalLockEnabled={true}
        scrollEventThrottle={16}
        bounces={false}
      >
        <View
          style={[styles.tabs, {width: this.state._containerWidth, }, this.props.tabsContainerStyle]}
          ref={'tabContainer'}
          onLayout={this.onTabContainerLayout}
        >
          {this.props.tabs.map((tab, i) => this.renderTabOption(tab, i))}
          <Animated.View style={[tabUnderlineStyle, dynamicTabUnderline, ]} />
        </View>
      </ScrollView>
    </View>;
  },

  onTabContainerLayout(e) {
    this._tabContainerMeasurements = e.nativeEvent.layout;
    let width = this._tabContainerMeasurements.width;
    if (width < WINDOW_WIDTH) {
      width = WINDOW_WIDTH;
    }
    this.setState({ _containerWidth: width, });
  },

  onContainerLayout(e) {
    this._containerMeasurements = e.nativeEvent.layout;
  },
});

module.exports = ScrollableTabBar;

const styles = StyleSheet.create({
  tab: {
    height: TAB_HEIGHT - 1,
    alignItems: 'center',
    justifyContent: 'center',
    paddingBottom: 30,
    paddingLeft: 20,
    paddingRight: 20,
  },
  container: {
    height: TAB_HEIGHT,
    borderWidth: 1,
    borderTopWidth: 0,
    borderLeftWidth: 0,
    borderRightWidth: 0,
    borderBottomColor: '#ccc',
  },
  tabs: {
    height: TAB_HEIGHT - 1,
    flexDirection: 'row',
    justifyContent: 'space-around',
  },
  scrollableContainer: {
    height: TAB_HEIGHT,
  },
});
<commit_msg>Add textStyle propType in ScrollableTabBar<commit_after>const React = require('react');
const ReactNative = require('react-native');
const {
  View,
  Animated,
  StyleSheet,
  ScrollView,
  TouchableOpacity,
  Text,
  Platform,
  findNodeHandle,
  Dimensions,
} = ReactNative;

const TAB_HEIGHT = 50;
const WINDOW_WIDTH = Dimensions.get('window').width;

const ScrollableTabBar = React.createClass({
  propTypes: {
    goToPage: React.PropTypes.func,
    activeTab: React.PropTypes.number,
    tabs: React.PropTypes.array,
    underlineColor: React.PropTypes.string,
    underlineHeight: React.PropTypes.number,
    backgroundColor: React.PropTypes.string,
    activeTextColor: React.PropTypes.string,
    inactiveTextColor: React.PropTypes.string,
    scrollOffset: React.PropTypes.number,
    style: View.propTypes.style,
    tabStyle: View.propTypes.style,
    tabsContainerStyle: View.propTypes.style,
    textStyle: View.propTypes.style,
  },

  getDefaultProps() {
    return {
      scrollOffset: 52,
      activeTextColor: 'navy',
      inactiveTextColor: 'black',
      underlineColor: 'navy',
      backgroundColor: null,
      underlineHeight: 4,
      style: {},
      tabStyle: {},
      tabsContainerStyle: {},
    };
  },

  getInitialState() {
    this._tabsMeasurements = [];
    return {
      _leftTabUnderline: new Animated.Value(0),
      _widthTabUnderline: new Animated.Value(0),
      _containerWidth: null,
    };
  },

  componentDidMount() {
    this.props.scrollValue.addListener(this.updateView);
  },

  updateView(offset) {
    const position = Math.floor(offset.value);
    const pageOffset = offset.value % 1;
    const tabCount = this.props.tabs.length;

    if (tabCount === 0 || offset.value < 0 || offset.value > tabCount - 1) {
      return;
    }

    if (this.necessarilyMeasurementsCompleted(position)) {
      this.updateTabPanel(position, pageOffset);
      this.updateTabUnderline(position, pageOffset, tabCount);
    }
  },

  necessarilyMeasurementsCompleted(position) {
    return this._tabsMeasurements[position] && this._tabsMeasurements[position + 1];
  },

  updateTabPanel(position, pageOffset) {
    const absolutePageOffset = pageOffset * this._tabsMeasurements[position].width;
    let newScrollX = this._tabsMeasurements[position].left + absolutePageOffset;

    newScrollX -= this.props.scrollOffset;
    newScrollX = newScrollX >= 0 ? newScrollX : 0;

    if (Platform === 'android') {
      this._scrollView.scrollTo({x: newScrollX, y: 0, });
    } else {
      const rightBoundScroll = this._tabContainerMeasurements.width - (this._containerMeasurements.width);
      newScrollX = newScrollX > rightBoundScroll ? rightBoundScroll : newScrollX;
      this._scrollView.scrollTo({x: newScrollX, y: 0, });
    }

  },

  updateTabUnderline(position, pageOffset, tabCount) {
    const lineLeft = this._tabsMeasurements[position].left;
    const lineRight = this._tabsMeasurements[position].right;

    if (position < tabCount - 1) {
      const nextTabLeft = this._tabsMeasurements[position + 1].left;
      const nextTabRight = this._tabsMeasurements[position + 1].right;

      const newLineLeft = (pageOffset * nextTabLeft + (1 - pageOffset) * lineLeft);
      const newLineRight = (pageOffset * nextTabRight + (1 - pageOffset) * lineRight);

      this.state._leftTabUnderline.setValue(newLineLeft);
      this.state._widthTabUnderline.setValue(newLineRight - newLineLeft);
    } else {
      this.state._leftTabUnderline.setValue(lineLeft);
      this.state._widthTabUnderline.setValue(lineRight - lineLeft);
    }
  },

  renderTabOption(name, page) {
    const isTabActive = this.props.activeTab === page;
    const { activeTextColor, inactiveTextColor, textStyle, } = this.props;
    const textColor = isTabActive ? activeTextColor : inactiveTextColor;
    const fontWeight = isTabActive ? 'bold' : 'normal';

    return <TouchableOpacity
      key={name}
      ref={'tab_' + page}
      accessible={true}
      accessibilityLabel={name}
      accessibilityTraits='button'
      style={[styles.tab, this.props.tabStyle]}
      onPress={() => this.props.goToPage(page)}
      onLayout={this.measureTab.bind(this, page)}
    >
      <View>
        <Text style={[{color: textColor, fontWeight, }, textStyle, ]}>
          {name}
        </Text>
      </View>
    </TouchableOpacity>;
  },

  measureTab(page) {
    const tabContainerhandle = findNodeHandle(this.refs.tabContainer);
    this.refs['tab_' + page].measureLayout(tabContainerhandle, (ox, oy, width, height, pageX, pageY) => {
      this._tabsMeasurements[page] = {left: ox, right: ox + width, width: width, height: height, };

      this.updateView({value: this.props.scrollValue._value, });
    });
  },

  render() {
    const tabUnderlineStyle = {
      position: 'absolute',
      height: this.props.underlineHeight,
      backgroundColor: this.props.underlineColor,
      bottom: 0,
    };

    const dynamicTabUnderline = {
      left: this.state._leftTabUnderline,
      width: this.state._widthTabUnderline,
    };

    return  <View
      style={[styles.container, {backgroundColor: this.props.backgroundColor, }, this.props.style]}
      onLayout={this.onContainerLayout}
    >
      <ScrollView
        ref={(scrollView) => { this._scrollView = scrollView; }}
        horizontal={true}
        showsHorizontalScrollIndicator={false}
        showsVerticalScrollIndicator={false}
        style={styles.scrollableContainer}
        directionalLockEnabled={true}
        scrollEventThrottle={16}
        bounces={false}
      >
        <View
          style={[styles.tabs, {width: this.state._containerWidth, }, this.props.tabsContainerStyle]}
          ref={'tabContainer'}
          onLayout={this.onTabContainerLayout}
        >
          {this.props.tabs.map((tab, i) => this.renderTabOption(tab, i))}
          <Animated.View style={[tabUnderlineStyle, dynamicTabUnderline, ]} />
        </View>
      </ScrollView>
    </View>;
  },

  onTabContainerLayout(e) {
    this._tabContainerMeasurements = e.nativeEvent.layout;
    let width = this._tabContainerMeasurements.width;
    if (width < WINDOW_WIDTH) {
      width = WINDOW_WIDTH;
    }
    this.setState({ _containerWidth: width, });
  },

  onContainerLayout(e) {
    this._containerMeasurements = e.nativeEvent.layout;
  },
});

module.exports = ScrollableTabBar;

const styles = StyleSheet.create({
  tab: {
    height: TAB_HEIGHT - 1,
    alignItems: 'center',
    justifyContent: 'center',
    paddingBottom: 30,
    paddingLeft: 20,
    paddingRight: 20,
  },
  container: {
    height: TAB_HEIGHT,
    borderWidth: 1,
    borderTopWidth: 0,
    borderLeftWidth: 0,
    borderRightWidth: 0,
    borderBottomColor: '#ccc',
  },
  tabs: {
    height: TAB_HEIGHT - 1,
    flexDirection: 'row',
    justifyContent: 'space-around',
  },
  scrollableContainer: {
    height: TAB_HEIGHT,
  },
});
<|endoftext|>


<commit_before>var gm = require('gm').subClass({imageMagick: true});
var http = require("http");
var fs = require("fs");
var path = require("path");

// -----------------------------------------------------------------
function log(info) {
	console.log('--------------------------');
	for(var i = 0; i < arguments.length; i++) {
		console.log(arguments[i]);
	}
}

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

function Poster(){

};

module.exports = Poster;
// -----------------------------------------------------------------

// 需要的参数：
// 1. 原始图片
// 2. 用户图片
// 3. 用户名称
// 4. 用户关键字

Poster.prototype.fillWord = function(options, callback) {
	log("fillWord: Hi, I am called!");

	if(!options
		|| !options.hasOwnProperty("imagePath")
		|| !options.hasOwnProperty("word")
		|| !options.hasOwnProperty("username")) {
		log("fillWord: options illegal", options);
	} else {
		var _image = path.join(__dirname, '../img/target/', Math.random().toString(36).substr(2) + ".jpg");

		var imagePath = options.imagePath || "../img/canvas.jpg";
		var word = options.word || "幸福！";
		var username = options.username || "开业啦！";
		log("username: " + username , "word: " + word)
		gm(imagePath)
		.stroke("#FFCD5C")
		.fill("#FFCD5C")
		.font("pingfangregular.ttf", 58)
		.drawText(240, 440, username)
		.font("pingfangregular.ttf", 180)
		.drawText(200,840, word)
		.write(_image, function (err) {
		  if(err) {
		  	log("fillWord: write file error", err);
		  	callback(err, null);
		  } else {
		  	log("fillWord: write file succeed");
		  	callback(err, _image);
		  }
		});
	}
}

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

Poster.prototype.handlePhoto = function(options, callback) {
	log("handlePhoto: Hi, I am called!");

	if(!options
		|| !options.hasOwnProperty("image")
		|| !options.hasOwnProperty("userimage")) {
		log("handlePhoto: options illegal", options);
		callback("handlePhoto: options illegal", null);
	} else {
		var image = options.image; // 背景图片
		var userimage = options.userimage; // 用户图像
		// 合成图片
		gm()
		.in('-page', '+0+0')  // Custom place for each of the images
		.in(image)
		.in('-page', '+256+100')
		.in(userimage)
		.quality(100)
		.mosaic()  // Merges the images as a matrix
		.write(image, function (err) {
		    if (err) {
		    	log("handlePhoto: handle photo error", err);
		    	callback(err);
		    } else {
		    	log("handlePhoto: handle photo succeed.");
		    	callback(null);
		    }
		});
	}
}

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

Poster.prototype.getWxUserImg = function(options, callback) {
	log("getWxUserImg: Hi, I am called.");

	if(!options
		|| !options.hasOwnProperty("headimgurl")
		|| !options.hasOwnProperty("openid")) {
		log("getWxUserImg: options illegal", options);
		callback("getWxUserImg: options illegal", null);
	} else {
		var headimgurl = options.headimgurl;
		var openid = options.openid;
		var userimg = path.join(__dirname, '../img/target/', openid + '.jpg');

		// 下载图片
		http.get(headimgurl, function(res){
	    var imgData = "";

	    //一定要设置response的编码为binary否则会下载下来的图片打不开
	    res.setEncoding("binary");

	    res.on("data", function(chunk){
        imgData+=chunk;
	    });

	    res.on("end", function(){
        fs.writeFile(userimg, imgData, "binary", function(err){
          if(err){
            log("getWxUserImg: write file error", err);
            callback(err, null);
          } else {
          	log("getWxUserImg: download file succeed");
          	var userOptions = {
          		userimg: userimg
          	}
          	callback(null, userOptions);
          }
        });
	    });
		});
	}
}

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

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

<commit_msg>adjust<commit_after>var gm = require('gm').subClass({imageMagick: true});
var http = require("http");
var fs = require("fs");
var path = require("path");

// -----------------------------------------------------------------
function log(info) {
	console.log('--------------------------');
	for(var i = 0; i < arguments.length; i++) {
		console.log(arguments[i]);
	}
}

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

function Poster(){

};

module.exports = Poster;
// -----------------------------------------------------------------

// 需要的参数：
// 1. 原始图片
// 2. 用户图片
// 3. 用户名称
// 4. 用户关键字

Poster.prototype.fillWord = function(options, callback) {
	log("fillWord: Hi, I am called!");

	if(!options
		|| !options.hasOwnProperty("imagePath")
		|| !options.hasOwnProperty("word")
		|| !options.hasOwnProperty("username")) {
		log("fillWord: options illegal", options);
	} else {
		var _image = path.join(__dirname, '../img/target/', Math.random().toString(36).substr(2) + ".jpg");

		var imagePath = options.imagePath || "../img/canvas.jpg";
		var word = options.word || "幸福！";
		var username = options.username || "开业啦！";
		log("username: " + username , "word: " + word)
		gm(imagePath)
		.stroke("#FFCD5C")
		.fill("#FFCD5C")
		.font("pingfangregular.ttf", 58)
		.drawText(240, 440, username)
		.font("pingfangregular.ttf", 180)
		.drawText(200,840, word)
		.write(_image, function (err) {
			log(arguments)
		  if(err) {
		  	log("fillWord: write file error", err);
		  	callback(err, null);
		  } else {
		  	log("fillWord: write file succeed");
		  	callback(err, _image);
		  }
		});
	}
}

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

Poster.prototype.handlePhoto = function(options, callback) {
	log("handlePhoto: Hi, I am called!");

	if(!options
		|| !options.hasOwnProperty("image")
		|| !options.hasOwnProperty("userimage")) {
		log("handlePhoto: options illegal", options);
		callback("handlePhoto: options illegal", null);
	} else {
		var image = options.image; // 背景图片
		var userimage = options.userimage; // 用户图像
		// 合成图片
		gm()
		.in('-page', '+0+0')  // Custom place for each of the images
		.in(image)
		.in('-page', '+256+100')
		.in(userimage)
		.quality(100)
		.mosaic()  // Merges the images as a matrix
		.write(image, function (err) {
		    if (err) {
		    	log("handlePhoto: handle photo error", err);
		    	callback(err);
		    } else {
		    	log("handlePhoto: handle photo succeed.");
		    	callback(null);
		    }
		});
	}
}

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

Poster.prototype.getWxUserImg = function(options, callback) {
	log("getWxUserImg: Hi, I am called.");

	if(!options
		|| !options.hasOwnProperty("headimgurl")
		|| !options.hasOwnProperty("openid")) {
		log("getWxUserImg: options illegal", options);
		callback("getWxUserImg: options illegal", null);
	} else {
		var headimgurl = options.headimgurl;
		var openid = options.openid;
		var userimg = path.join(__dirname, '../img/target/', openid + '.jpg');

		// 下载图片
		http.get(headimgurl, function(res){
	    var imgData = "";

	    //一定要设置response的编码为binary否则会下载下来的图片打不开
	    res.setEncoding("binary");

	    res.on("data", function(chunk){
        imgData+=chunk;
	    });

	    res.on("end", function(){
        fs.writeFile(userimg, imgData, "binary", function(err){
          if(err){
            log("getWxUserImg: write file error", err);
            callback(err, null);
          } else {
          	log("getWxUserImg: download file succeed");
          	var userOptions = {
          		userimg: userimg
          	}
          	callback(null, userOptions);
          }
        });
	    });
		});
	}
}

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

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

<|endoftext|>


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

function potter(extracts, pots) {
    pots = pots || {};
    extracts.forEach(function(text) {
        add_to_pots(pots, text);
    });
    return pots;
}

potter.defaults = {
    charset: 'utf-8',
    headers: {
        'project-id-version': 'PACKAGE VERSION',
        'language-team': 'LANGUAGE <LL@li.org>',
        'po-revision-date': 'YEAR-MO-DA HO:MI+ZONE',
        'language': '',
        'mime-version': '1.0',
        'content-transfer-encoding': '8bit'
    }
};

function add_to_pots(pots, text) {
    var pot = pots[text.domain] || new_pot();
    pots[text.domain] = pot;

    var translations = pot.translations[text.context] || {};
    pot.translations[text.context] = translations;

    var translation = translations[text.key];
    if (!translation) {
        translations[text.key] = new_translation(text);
    }
    else {
        add_to_translation(translation, text);
    }
}

function new_pot() {
    return {
        charset: potter.defaults.charset,
        headers: _(potter.defaults.headers).clone(),
        translations: {}
    };
}

function translation_reference(text) {
    return [text.filename,text.line].join(':');
}

function new_translation(text) {
    var translation = {
        msgid: text.key,
        msgstr: text.plural
            ? ['', '']
            : [''],
        msgctx: text.context,
        comments: {reference: translation_reference(text)}
    };

    if (text.plural) {
        translation.msgid_plural = text.plural;
    }

    return translation;
}

function add_to_translation(translation, text) {
    var reference = translation_reference(text);
    if (translation.comments.reference.indexOf(reference) < 0) {
        translation.comments.reference = [
            translation.comments.reference,
            reference
        ].join(' ');
    }
}

module.exports = potter;
<commit_msg>Add missing space from array join in potter.translation_reference<commit_after>var _ = require('underscore');

function potter(extracts, pots) {
    pots = pots || {};
    extracts.forEach(function(text) {
        add_to_pots(pots, text);
    });
    return pots;
}

potter.defaults = {
    charset: 'utf-8',
    headers: {
        'project-id-version': 'PACKAGE VERSION',
        'language-team': 'LANGUAGE <LL@li.org>',
        'po-revision-date': 'YEAR-MO-DA HO:MI+ZONE',
        'language': '',
        'mime-version': '1.0',
        'content-transfer-encoding': '8bit'
    }
};

function add_to_pots(pots, text) {
    var pot = pots[text.domain] || new_pot();
    pots[text.domain] = pot;

    var translations = pot.translations[text.context] || {};
    pot.translations[text.context] = translations;

    var translation = translations[text.key];
    if (!translation) {
        translations[text.key] = new_translation(text);
    }
    else {
        add_to_translation(translation, text);
    }
}

function new_pot() {
    return {
        charset: potter.defaults.charset,
        headers: _(potter.defaults.headers).clone(),
        translations: {}
    };
}

function translation_reference(text) {
    return [text.filename, text.line].join(':');
}

function new_translation(text) {
    var translation = {
        msgid: text.key,
        msgstr: text.plural
            ? ['', '']
            : [''],
        msgctx: text.context,
        comments: {reference: translation_reference(text)}
    };

    if (text.plural) {
        translation.msgid_plural = text.plural;
    }

    return translation;
}

function add_to_translation(translation, text) {
    var reference = translation_reference(text);
    if (translation.comments.reference.indexOf(reference) < 0) {
        translation.comments.reference = [
            translation.comments.reference,
            reference
        ].join(' ');
    }
}

module.exports = potter;
<|endoftext|>


<commit_before>const mongodb = require("mongodb");
const ObjectID = mongodb.ObjectID;

module.exports = function(o = {}) {
    const db = require("../db")(o);

    // I don't want mongo formatted ids getting out of this service -
    // that's an implementation detail. However, mongo doesn't seem
    // to have the ability of simply returning its ids as strings
    // to begin with. Bit of a pita, but hey...
    function replaceId(item) {
	if (item._id) item._id = item._id.toHexString();
	return item;
    }

    function createGroupingPipeline(selector, desc, includeDataItems) {
	let pipeline = [
	    {
    		$group: {
    		    // must use _id at this point for the group key
    		    _id: "$" + selector,
    		    count: {
    			$sum: 1
    		    }
    		}
    	    },
    	    {
    		$project: {
    		    // rename _id to key
    		    _id: 0,
    		    key: "$_id",
    		    count: 1
    		}
    	    }
	];
	let sort = {
	    $sort: {}
	};
	sort.$sort[selector] = desc ? -1 : 1;

    	if (includeDataItems) {
    	    // include items directly if we're expected to do so, and if this is the
    	    // most deeply nested group in case there are several
    	    pipeline[0].$group.items = {
    		$push: "$$CURRENT"
    	    };
    	    pipeline[1].$project.items = 1;
    	}
    	else {
    	    // add null items field otherwise
    	    pipeline.push({
    		$addFields: {
    		    items: null // only null works, not [] or leaving out items altogether
    		}
    	    });
    	}

	return pipeline;
    }

    function createSkipTakePipeline(skip, take) {
	let pipeline = [];

	if (skip) pipeline.push({
    	    $skip: skip
    	});
    	if (take) pipeline.push({
    	    $limit: take
    	});

	return pipeline;
    }

    function createCountPipeline() {
	return [{
	    $count: "count"
	}];
    }

    function createMatchPipeline(selector, value) {
	let match = {
	    $match: {}
	};
	match.$match[selector] = value;
	return [match];
    }

    async function queryGroupData(collection, selector, desc, includeDataItems, skip, take, matchPipeline) {
	const pipeline = matchPipeline.concat(
	    createGroupingPipeline(selector, desc, includeDataItems),
	    createSkipTakePipeline(skip, take)
	);
	const groupData = await collection.aggregate(pipeline).toArray();
	if (includeDataItems) {
	    for (const groupItem of groupData) {
		groupItem.items = groupItem.items.map(replaceId);
	    }
	}
	return groupData;
    }

    async function queryGroup(collection, params, groupIndex, matchPipeline=[]) {
	const group = params.group[groupIndex];
	const lastGroup = groupIndex === params.group.length - 1;
	const itemDataRequired = lastGroup && group.isExpanded;
	const subGroupsRequired = (!lastGroup) && group.isExpanded;

	const groupData = await queryGroupData(collection, group.selector, group.desc, itemDataRequired, params.skip, params.take, matchPipeline);
	if (subGroupsRequired) {
	    for (const groupDataItem of groupData) {
		groupDataItem.items = await queryGroup(
		    collection, params, groupIndex + 1,
		    matchPipeline.concat(createMatchPipeline(group.selector, groupDataItem.key)));
	    }
	}

	return groupData;
    }

    async function queryGroups(collection, params) {
	const topLevelGroupData = await queryGroup(collection, params, 0);
	console.log("Top level group data", topLevelGroupData);

	const group = params.group[0];
	const countPipeline = createGroupingPipeline(group.selector, group.desc, false).concat(createCountPipeline());
	console.log("count pipeline", countPipeline);

	const groupCount = (await collection.aggregate(countPipeline).toArray())[0].count;
	console.log("Group Count: ", groupCount);

	return {
	    data: topLevelGroupData,
	    groupCount: groupCount
	};
    }

    function parseFilter(element) {
	// Element is assumed to be an array with two or three items.
	// For two items:
	// 0: unary operator
	// 1: operand
	//
	// For three items:
	// 0: operand 1 - this is described as the "getter" in the docs - i.e. field name -
	//    but in the cases of "and" and "or" it could be another nested element
	// 1: operator
	// 2: operand 2 - the value for comparison - for "and" and "or" can be a nested element

	function error(msg) {
	    throw msg + " Element: " + JSON.stringify(element);
	}

	function construct(fieldName, operator, compValue) {
	    let result = {};
	    result[fieldName] = {};
	    result[fieldName][operator] = compValue;
	    return result;
	}

	function constructRegex(fieldName, regex) {
	    let result = {};
	    result[fieldName] = {
		$regex: regex,
		$options: "" // "i" for case-insensitive?
	    };
	    return result;
	}

	if (element.length === 2) {
	    // unary operator - only one supported
	    if (element[0] === "!") {
		return {
		    $nor: [
			parseFilter(element[1])
		    ]
		};
	    }
	    else return error("Unsupported unary operator");
	}
	else if (element.length === 3) {
	    switch(element[1].toLowerCase()) {
	    case "and":
		return {
		    $and: [
			parseFilter(element[0]),
			parseFilter(element[2])
		    ]
		};
	    case "or":
		return {
		    $or: [
			parseFilter(element[0]),
			parseFilter(element[2])
		    ]
		};
	    case "=":
		return construct(element[0], "$eq", element[2]);
	    case "<>":
		return construct(element[0], "$ne", element[2]);
	    case ">":
		return construct(element[0], "$gt", element[2]);
	    case ">=":
		return construct(element[0], "$gte", element[2]);
	    case "<":
		return construct(element[0], "$lt", element[2]);
	    case "<=":
		return construct(element[0], "$lte", element[2]);
	    case "startswith":
		return constructRegex(element[0], "^" + element[2]);
	    case "endswith":
		return constructRegex(element[0], element[2] + "$");
	    case "contains":
		return constructRegex(element[0], element[2]);
	    case "notcontains":
		return constructRegex(element[0], "^((?!" + element[2] + ").)*$");
	    default: return error("Unknown operator");
	    }
	}
	else return error("Element is too long");
    }

    async function querySimple(collection, params = {}) {
	const criteria =
		  params.filter ? parseFilter(params.filter) : {};

	let results = collection.find(criteria);

	if (params.sort) {
	    // there is indication that sort may vary in the following ways
	    // that are currently unsupported:
	    // * sort may be a single instance instead of an array
	    // * sort instance may be a string
	    // * sort instance may be a function (but then it wouldn't get into
	    //   this function in the first place)
	    let sorting = {};
	    for (const sf of params.sort) sorting[sf.selector] = sf.desc ? -1 : 1;

	    results = results.sort(sorting);
	}

	if (params.skip) results = results.skip(params.skip);
	if (params.take) results = results.limit(params.take);

	return {
	    data: (await results.toArray()).map(replaceId)
	};
    }

    function sendResult(totalCount, queryResult, params = {}, r) {
	let reply = {
	    params: params,
	    totalCount: totalCount,
	    groupCount: queryResult.groupCount,
	    data: queryResult.data
	};

	r(null, reply);
    }

    this.add("role:entitiesQuery, domain:values, cmd:list", (m, r) => {
	db(async (db) => {
	    const collection = db.collection("values");

	    try {
		const totalCount = await collection.count();
		const queryResult =
			  m.params && m.params.group && m.params.group.length > 0 ?
			  await queryGroups(collection, m.params) :
			  await querySimple(collection, m.params);

		sendResult(totalCount, queryResult, m.params, r);
	    }
	    catch(err) {
		r(null, { err$: err });
	    }
	});
    });

    this.add("role:entitiesQuery, domain:values, cmd:fetch", (m, r) => {
	db(async (db) => {
	    try {
		const res = await db.collection("values").findOne({ _id: new ObjectID(m.id) });
		if (res) r(null, replaceId(res));
		else r(null, { err$: "unknownid" });
	    }
	    catch(err) {
		r(null, { err$: err });
	    }
	});
    });
};
<commit_msg>added filter logic for simple string values<commit_after>const mongodb = require("mongodb");
const ObjectID = mongodb.ObjectID;

const fixObject = require("../message-utils").fixObject;

module.exports = function(o = {}) {
    const db = require("../db")(o);

    // I don't want mongo formatted ids getting out of this service -
    // that's an implementation detail. However, mongo doesn't seem
    // to have the ability of simply returning its ids as strings
    // to begin with. Bit of a pita, but hey...
    function replaceId(item) {
	if (item._id) item._id = item._id.toHexString();
	return item;
    }

    function createGroupingPipeline(selector, desc, includeDataItems) {
	let pipeline = [
	    {
    		$group: {
    		    // must use _id at this point for the group key
    		    _id: "$" + selector,
    		    count: {
    			$sum: 1
    		    }
    		}
    	    },
    	    {
    		$project: {
    		    // rename _id to key
    		    _id: 0,
    		    key: "$_id",
    		    count: 1
    		}
    	    }
	];
	let sort = {
	    $sort: {}
	};
	sort.$sort[selector] = desc ? -1 : 1;

    	if (includeDataItems) {
    	    // include items directly if we're expected to do so, and if this is the
    	    // most deeply nested group in case there are several
    	    pipeline[0].$group.items = {
    		$push: "$$CURRENT"
    	    };
    	    pipeline[1].$project.items = 1;
    	}
    	else {
    	    // add null items field otherwise
    	    pipeline.push({
    		$addFields: {
    		    items: null // only null works, not [] or leaving out items altogether
    		}
    	    });
    	}

	return pipeline;
    }

    function createSkipTakePipeline(skip, take) {
	let pipeline = [];

	if (skip) pipeline.push({
    	    $skip: skip
    	});
    	if (take) pipeline.push({
    	    $limit: take
    	});

	return pipeline;
    }

    function createCountPipeline() {
	return [{
	    $count: "count"
	}];
    }

    function createMatchPipeline(selector, value) {
	let match = {
	    $match: {}
	};
	match.$match[selector] = value;
	return [match];
    }

    async function queryGroupData(collection, selector, desc, includeDataItems, skip, take, matchPipeline) {
	const pipeline = matchPipeline.concat(
	    createGroupingPipeline(selector, desc, includeDataItems),
	    createSkipTakePipeline(skip, take)
	);
	const groupData = await collection.aggregate(pipeline).toArray();
	if (includeDataItems) {
	    for (const groupItem of groupData) {
		groupItem.items = groupItem.items.map(replaceId);
	    }
	}
	return groupData;
    }

    async function queryGroup(collection, params, groupIndex, matchPipeline=[]) {
	const group = params.group[groupIndex];
	const lastGroup = groupIndex === params.group.length - 1;
	const itemDataRequired = lastGroup && group.isExpanded;
	const subGroupsRequired = (!lastGroup) && group.isExpanded;

	const groupData = await queryGroupData(collection, group.selector, group.desc, itemDataRequired, params.skip, params.take, matchPipeline);
	if (subGroupsRequired) {
	    for (const groupDataItem of groupData) {
		groupDataItem.items = await queryGroup(
		    collection, params, groupIndex + 1,
		    matchPipeline.concat(createMatchPipeline(group.selector, groupDataItem.key)));
	    }
	}

	return groupData;
    }

    async function queryGroups(collection, params) {
	const topLevelGroupData = await queryGroup(collection, params, 0);
	console.log("Top level group data", topLevelGroupData);

	const group = params.group[0];
	const countPipeline = createGroupingPipeline(group.selector, group.desc, false).concat(createCountPipeline());
	console.log("count pipeline", countPipeline);

	const groupCount = (await collection.aggregate(countPipeline).toArray())[0].count;
	console.log("Group Count: ", groupCount);

	return {
	    data: topLevelGroupData,
	    groupCount: groupCount
	};
    }

    function parseFilter(element) {
	// Element can be a string denoting a field name - I don't know if that's a case
	// supported by the widgets in any way, but it seems conceivable that somebody constructs
	// an expression like [ "!", "boolValueField" ]
	// In the string case, I return a truth-checking filter.
	//
	// Otherwise, element is assumed to be an array with two or three items.
	// For two items:
	// 0: unary operator
	// 1: operand
	//
	// For three items:
	// 0: operand 1 - this is described as the "getter" in the docs - i.e. field name -
	//    but in the cases of "and" and "or" it could be another nested element
	// 1: operator
	// 2: operand 2 - the value for comparison - for "and" and "or" can be a nested element

	function error(msg) {
	    throw msg + " Element: " + JSON.stringify(element);
	}

	function construct(fieldName, operator, compValue) {
	    let result = {};
	    result[fieldName] = {};
	    result[fieldName][operator] = compValue;
	    return result;
	}

	function constructRegex(fieldName, regex) {
	    let result = {};
	    result[fieldName] = {
		$regex: regex,
		$options: "" // "i" for case-insensitive?
	    };
	    return result;
	}

	if (typeof element === "string") {
	    return construct(element, "$eq", true);
	}
	else if (element.length) {
	    if (element.length === 2) {
		// unary operator - only one supported
		if (element[0] === "!") {
		    return {
			$nor: [
			    parseFilter(element[1])
			]
		    };
		}
		else return error("Unsupported unary operator");
	    }
	    else if (element.length === 3) {
		switch(element[1].toLowerCase()) {
		case "and":
		    return {
			$and: [
			    parseFilter(element[0]),
			    parseFilter(element[2])
			]
		    };
		case "or":
		    return {
			$or: [
			    parseFilter(element[0]),
			    parseFilter(element[2])
			]
		    };
		case "=":
		    return construct(element[0], "$eq", element[2]);
		case "<>":
		    return construct(element[0], "$ne", element[2]);
		case ">":
		    return construct(element[0], "$gt", element[2]);
		case ">=":
		    return construct(element[0], "$gte", element[2]);
		case "<":
		    return construct(element[0], "$lt", element[2]);
		case "<=":
		    return construct(element[0], "$lte", element[2]);
		case "startswith":
		    return constructRegex(element[0], "^" + element[2]);
		case "endswith":
		    return constructRegex(element[0], element[2] + "$");
		case "contains":
		    return constructRegex(element[0], element[2]);
		case "notcontains":
		    return constructRegex(element[0], "^((?!" + element[2] + ").)*$");
		default: return error("Unknown operator");
		}
	    }
	    else return error("Array element of unsupported length");
	}
	else return error("Element type unknown");
    }

    async function querySimple(collection, params = {}) {
	const criteria =
		  params.filter ? parseFilter(params.filter) : {};

	let results = collection.find(criteria);

	if (params.sort) {
	    // there is indication that sort may vary in the following ways
	    // that are currently unsupported:
	    // * sort may be a single instance instead of an array
	    // * sort instance may be a string
	    // * sort instance may be a function (but then it wouldn't get into
	    //   this function in the first place)
	    let sorting = {};
	    for (const sf of params.sort) sorting[sf.selector] = sf.desc ? -1 : 1;

	    results = results.sort(sorting);
	}

	if (params.skip) results = results.skip(params.skip);
	if (params.take) results = results.limit(params.take);

	return {
	    data: (await results.toArray()).map(replaceId)
	};
    }

    function sendResult(totalCount, queryResult, params = {}, r) {
	let reply = {
	    params: params,
	    totalCount: totalCount,
	    groupCount: queryResult.groupCount,
	    data: queryResult.data
	};

	r(null, reply);
    }

    this.add("role:entitiesQuery, domain:values, cmd:list", (m, r) => {
	m = fixObject(m);

	db(async (db) => {
	    const collection = db.collection("values");

	    try {
		const totalCount = await collection.count();
		const queryResult =
			  m.params && m.params.group && m.params.group.length > 0 ?
			  await queryGroups(collection, m.params) :
			  await querySimple(collection, m.params);

		sendResult(totalCount, queryResult, m.params, r);
	    }
	    catch(err) {
		r(null, { err$: err });
	    }
	});
    });

    this.add("role:entitiesQuery, domain:values, cmd:fetch", (m, r) => {
	db(async (db) => {
	    try {
		const res = await db.collection("values").findOne({ _id: new ObjectID(m.id) });
		if (res) r(null, replaceId(res));
		else r(null, { err$: "unknownid" });
	    }
	    catch(err) {
		r(null, { err$: err });
	    }
	});
    });
};
<|endoftext|>


<commit_before>
var inherits = require('util').inherits
var Feature = require('./feature')

module.exports = Transform

inherits(Transform, Feature)

function Transform(options) {
  if (!(this instanceof Transform)) return new Transform(options)

  options.name = options.name || options.module.replace(/^es6-/, '')
  Feature.call(this, options)
}

// .transform(ast) with lazy laoding
Transform.prototype.transform = function (ast) {
  return this.module.transform(ast)
}

Transform.transforms = []
Transform.transform = {}
Transform.register = function (obj) {
  var transform = new Transform(obj)
  Transform.transform[transform.name] =
  Transform.transform[transform.shortName] = transform
  Transform.transforms.push(transform)
}

Transform.register({
  module: 'es6-destructuring'
})

Transform.register({
  module: 'es6-shorthands',
})

Transform.register({
  module: 'es6-class',
})

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/arrow_functions
Transform.register({
  module: 'es6-arrow-function',
  shortName: 'arrowfn',
  browsers: {
    ff: 24, // read firefox notes
  }
})

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
Transform.register({
  name: 'generators',
  module: 'regenerator',
  shortName: 'gens',
  runtime: 'regenerator/runtime.js',
  browsers: {
    // chrome is behind a flag still, which doesn't count
    // http://www.chromestatus.com/features/4959347197083648#generator
    ff: 26,
  }
})

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings
Transform.register({
  module: 'es6-templates',
})

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/default_parameters
Transform.register({
  module: 'es6-default-params',
  browsers: {
    ff: 15
  }
})

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/rest_parameters
Transform.register({
  module: 'es6-rest-params',
  browsers: {
    ff: 15
  }
})

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
Transform.register({
  module: 'es6-spread',
  browser: {
    ff: 27
  }
})

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Array_comprehensions
Transform.register({
  module: 'es6-comprehensions',
  browsers: {
    ff: 30
  }
})
<commit_msg>shorter short names<commit_after>
var inherits = require('util').inherits
var Feature = require('./feature')

module.exports = Transform

inherits(Transform, Feature)

function Transform(options) {
  if (!(this instanceof Transform)) return new Transform(options)

  options.name = options.name || options.module.replace(/^es6-/, '')
  Feature.call(this, options)
}

// .transform(ast) with lazy laoding
Transform.prototype.transform = function (ast) {
  return this.module.transform(ast)
}

Transform.transforms = []
Transform.transform = {}
Transform.register = function (obj) {
  var transform = new Transform(obj)
  Transform.transform[transform.name] =
  Transform.transform[transform.shortName] = transform
  Transform.transforms.push(transform)
}

Transform.register({
  module: 'es6-destructuring',
  shortName: 'destruct',
})

Transform.register({
  module: 'es6-shorthands',
})

Transform.register({
  module: 'es6-class',
  shortName: 'cls',
})

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/arrow_functions
Transform.register({
  module: 'es6-arrow-function',
  shortName: 'arrowfn',
  browsers: {
    ff: 24, // read firefox notes
  }
})

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
Transform.register({
  name: 'generators',
  module: 'regenerator',
  shortName: 'gens',
  runtime: 'regenerator/runtime.js',
  browsers: {
    // chrome is behind a flag still, which doesn't count
    // http://www.chromestatus.com/features/4959347197083648#generator
    ff: 26,
  }
})

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings
Transform.register({
  module: 'es6-templates',
  shortName: 'tmpls',
})

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/default_parameters
Transform.register({
  module: 'es6-default-params',
  shortName: 'def-prms',
  browsers: {
    ff: 15
  }
})

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/rest_parameters
Transform.register({
  module: 'es6-rest-params',
  shortName: 'rest-prms',
  browsers: {
    ff: 15
  }
})

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
Transform.register({
  module: 'es6-spread',
  shortName: 'sprd',
  browser: {
    ff: 27
  }
})

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Array_comprehensions
Transform.register({
  module: 'es6-comprehensions',
  shortName: 'cmprhsns',
  browsers: {
    ff: 30
  }
})
<|endoftext|>


<commit_before>var path = require('path')
var fs = require('fs')
var Router = require('koa-router')
var router = new Router()

var RELOAD_FILE = path.join(__dirname, './reload-client.js')

module.exports = function reload (httpServer, koaApp, verboseLogging) {
  var reloadCode = fs.readFileSync(RELOAD_FILE, 'utf8')

  var conn

  var WebSocketServer = require('ws').Server
  var wss = new WebSocketServer({ server: httpServer })

  wss.on('connection', (ws) => {
    // Take the current web socket connection and save it to webSocketConnetion so we can use it later in the returned reload function for manually firing reload events.
    conn = ws

    if (verboseLogging) {
      console.log('Reload client connected to server')
    }
  })

  if (verboseLogging) {
    reloadCode = reloadCode.replace('verboseLogging = false', 'verboseLogging = true')
  }

  router.get('/reload/reload.js', function(ctx, next){
    ctx.type = 'text/javascript'
    ctx.body = reloadCode
  })

  koaApp.use(router.routes())
  koaApp.use(router.allowedMethods())

  // Return an object, so that the user can manually reload the server by calling the returned function reload. Using the web socket connection from above, we provide a function called reload which passes the command 'reload' to the function sendMessage. sendMessage sends the message 'reload' over the socket (if the socket is connected) to the client. The client then recieves the messages checks to see if the message is reload and then reloads the page.
  return {
    'server': reload,
    'connection': conn,
    'reload': function () {
      this.sendMessage('reload')
    },
    'sendMessage': function (command) {
      if (conn) {
        conn.send(command, function (error) {
          if (error) {
            console.error(error)
          }
        })
      } else {
        if (verboseLogging) {
          console.log('Cannot send "' + command + '" to client: still not connected')
        }
      }
    }
  }
}
<commit_msg>change router<commit_after>var path = require('path')
var fs = require('fs')
var Router = require('koa-router')
var RELOAD_FILE = path.join(__dirname, './reload-client.js')
var router = new Router()

module.exports = function reload (httpServer, verboseLogging) {
  var reloadCode = fs.readFileSync(RELOAD_FILE, 'utf8')

  var conn

  var WebSocketServer = require('ws').Server
  var wss = new WebSocketServer({ server: httpServer })

  wss.on('connection', (ws) => {
    // Take the current web socket connection and save it to webSocketConnetion so we can use it later in the returned reload function for manually firing reload events.
    conn = ws

    if (verboseLogging) {
      console.log('Reload client connected to server')
    }
  })

  if (verboseLogging) {
    reloadCode = reloadCode.replace('verboseLogging = false', 'verboseLogging = true')
  }

  router.get('/reload/reload.js', (ctx, next) => {
    ctx.type = 'text/javascript'
    ctx.body = reloadCode
  })

  // Return an object, so that the user can manually reload the server by calling the returned function reload. Using the web socket connection from above, we provide a function called reload which passes the command 'reload' to the function sendMessage. sendMessage sends the message 'reload' over the socket (if the socket is connected) to the client. The client then recieves the messages checks to see if the message is reload and then reloads the page.
  return {
    'Reloadrouter': router,
    'server': reload,
    'connection': conn,
    'reload': function () {
      this.sendMessage('reload')
    },
    'sendMessage': function (command) {
      if (conn) {
        conn.send(command, function (error) {
          if (error) {
            console.error(error)
          }
        })
      } else {
        if (verboseLogging) {
          console.log('Cannot send "' + command + '" to client: still not connected')
        }
      }
    }
  }
}
<|endoftext|>


<commit_before>/*
 * Posible opts
 * port: A port to run the reload websocket on (as a number). (Optional) (Default: `8080`)
 * route: The route reload will create for the script file. (Optional) (Default `reload/reload.js`)
 * verbose: Will show logging on the server and client side. (Optional) (Default: `false`)
 */
function reload (app, opts) {
  // Requires
  var path = require('path')
  var fs = require('fs')

  // Parameters variables
  var httpServerOrPort
  var expressApp
  var verboseLogging
  var port

  // Application variables
  var RELOAD_FILE = path.join(__dirname, './reload-client.js')
  var reloadCode = fs.readFileSync(RELOAD_FILE, 'utf8')
  var route

  // Websocket server variables
  var connections = new Set()
  var WebSocketServer = require('ws').Server
  var wss

  // General variables
  var socketPortSpecified

  opts = opts || {}

  if (arguments.length > 0 && (typeof (arguments[0]) === 'number' || typeof (arguments[0]) === 'object')) {
    if (typeof (arguments[0]) === 'number') { // If old arguments passed handle old arguments, the old arguments and their order were: httpServerOrPort, expressApp, verboseLogging,
      console.warn('Deprecated Warning: You supplied reload old arguments, please upgrade to the new parameters see: https://github.com/jprichardson/reload/tree/master#api-for-express')
      httpServerOrPort = arguments[0]
      expressApp = arguments[1]
      verboseLogging = arguments[2]

      socketPortSpecified = typeof httpServerOrPort === 'number' ? httpServerOrPort : null
    } else { // Setup options or use defaults
      expressApp = arguments[0]
      port = opts.port || 9856
      route = opts.route || '/reload/reload.js'
      verboseLogging = opts.verbose === true || opts.verbose === 'true' || false

      if (port) {
        socketPortSpecified = port
        httpServerOrPort = port
      }
    }
  } else {
    throw new Error('Lack of/invalid arguments provided to reload')
  }

  // Application setup
  if (verboseLogging) {
    reloadCode = reloadCode.replace('verboseLogging = false', 'verboseLogging = true')
  }

  if (socketPortSpecified) {
    reloadCode = reloadCode.replace('window.location.origin.replace()', 'window.location.origin.replace(/(^http(s?):\\/\\/)(.*:)(.*)/,' + (socketPortSpecified ? '\'ws$2://$3' + socketPortSpecified : 'ws$2://$3$4') + '\')')
  }

  expressApp.get(route, function (req, res) {
    res.type('text/javascript')
    res.send(reloadCode)
  })

  // Websocket server setup
  // Use custom user specified port
  if (socketPortSpecified) {
    wss = new WebSocketServer({ port: httpServerOrPort })
  } else { // Attach to server, using server's port. Kept here to support legacy arguments.
    wss = new WebSocketServer({ server: httpServerOrPort })
  }

  wss.on('connection', (ws) => {
    connections.add(ws)
    ws.on('close', function () {
      connections.delete(ws)
    })

    if (verboseLogging) {
      console.log('Reload client connected to server')
    }
  })

  function sendMessage (message) {
    if (verboseLogging) {
      console.log('Sending message to ' + (connections.size) + ' connections: ' + message)
    }
    for (let conn of connections) {
      conn.send(message, function (error) {
        if (error) {
          console.error(error)
        }
      })
    }
  }
  // Return an object, so that the user can manually reload the server by calling the returned function reload. Using the web socket connection from above, we provide a function called reload which passes the command 'reload' to the function sendMessage. sendMessage sends the message 'reload' over the socket (if the socket is connected) to the client. The client then recieves the messages checks to see if the message is reload and then reloads the page.
  return {
    'connections': connections,
    'server': reload,
    'reload': function () {
      sendMessage('reload')
    },
    'sendMessage': sendMessage
  }
}

module.exports = reload
<commit_msg>* Fixed legacy param checking. * Added a new error for legacy params * Cached array memeber<commit_after>/*
 * Posible opts
 * port: A port to run the reload websocket on (as a number). (Optional) (Default: `8080`)
 * route: The route reload will create for the script file. (Optional) (Default `reload/reload.js`)
 * verbose: Will show logging on the server and client side. (Optional) (Default: `false`)
 */
function reload (app, opts) {
  // Requires
  var path = require('path')
  var fs = require('fs')

  // Parameters variables
  var httpServerOrPort
  var expressApp
  var verboseLogging
  var port

  // Application variables
  var RELOAD_FILE = path.join(__dirname, './reload-client.js')
  var reloadCode = fs.readFileSync(RELOAD_FILE, 'utf8')
  var route

  // Websocket server variables
  var connections = new Set()
  var WebSocketServer = require('ws').Server
  var wss

  // General variables
  var socketPortSpecified
  var argumentZero = arguments[0]

  opts = opts || {}

  if (arguments.length > 0 && (typeof (argumentZero) === 'object' || typeof (argumentZero) === 'function')) {
    if (typeof (argumentZero) === 'object') { // If old arguments passed handle old arguments, the old arguments and their order were: httpServerOrPort, expressApp, and verboseLogging
      console.warn('Deprecated Warning: You supplied reload old arguments, please upgrade to the new parameters see: https://github.com/jprichardson/reload/tree/master#api-for-express')
      if (arguments.length < 2) {
        throw new TypeError('Lack of/invalid arguments provided to reload. It is recommened to update to the new arguments anyways, this would be a good time to do so.', 'reload.js', 7)
      }
      httpServerOrPort = argumentZero
      expressApp = arguments[1]
      verboseLogging = arguments[2]
      route = '/reload/reload.js';

    } else { // Setup options or use defaults
      expressApp = argumentZero
      port = opts.port || 9856
      route = opts.route || '/reload/reload.js'
      verboseLogging = opts.verbose === true || opts.verbose === 'true' || false

      if (port) {
        socketPortSpecified = port
        httpServerOrPort = port
      }
    }
  } else {
    throw new TypeError('Lack of/invalid arguments provided to reload', 'reload.js', 7)
  }

  // Application setup
  if (verboseLogging) {
    reloadCode = reloadCode.replace('verboseLogging = false', 'verboseLogging = true')
  }

  if (socketPortSpecified) {
    reloadCode = reloadCode.replace('window.location.origin.replace()', 'window.location.origin.replace(/(^http(s?):\\/\\/)(.*:)(.*)/,' + (socketPortSpecified ? '\'ws$2://$3' + socketPortSpecified : 'ws$2://$3$4') + '\')')
  }

  expressApp.get(route, function (req, res) {
    res.type('text/javascript')
    res.send(reloadCode)
  })

  // Websocket server setup
  // Use custom user specified port
  if (socketPortSpecified) {
    wss = new WebSocketServer({ port: httpServerOrPort })
  } else { // Attach to server, using server's port. Kept here to support legacy arguments.
    wss = new WebSocketServer({ server: httpServerOrPort })
  }

  wss.on('connection', (ws) => {
    connections.add(ws)
    ws.on('close', function () {
      connections.delete(ws)
    })

    if (verboseLogging) {
      console.log('Reload client connected to server')
    }
  })

  function sendMessage (message) {
    if (verboseLogging) {
      console.log('Sending message to ' + (connections.size) + ' connections: ' + message)
    }
    for (let conn of connections) {
      conn.send(message, function (error) {
        if (error) {
          console.error(error)
        }
      })
    }
  }
  // Return an object, so that the user can manually reload the server by calling the returned function reload. Using the web socket connection from above, we provide a function called reload which passes the command 'reload' to the function sendMessage. sendMessage sends the message 'reload' over the socket (if the socket is connected) to the client. The client then recieves the messages checks to see if the message is reload and then reloads the page.
  return {
    'connections': connections,
    'server': reload,
    'reload': function () {
      sendMessage('reload')
    },
    'sendMessage': sendMessage
  }
}

module.exports = reload
<|endoftext|>


<commit_before>'use strict';

/**
 * A remote client that sends request to a pooled-pg server.
 * (C) 2015 Alex Fernández.
 */

// requires
require('prototypes');
var net = require('net');
var server = require('./server.js');
var testing = require('testing');

// constants
var TEST_PORT = 5444;
var TEST_ADDRESS = 'pooled://test:test@localhost: ' + TEST_PORT +  '/test';

// globals
var clients = [];

exports.remoteConnect = function(address, callback)
{
	var client = new exports.RemoteClient(address);
	callback(null, client, client.done);
};

exports.end = function()
{
	clients.forEach(function(client)
	{
		client.end();
	});
};

exports.RemoteClient = function(address)
{
	// self-reference
	var self = this;

	// init
	clients.push(self);

	function connect(callback)
	{
		var fullHost = address.substringFrom('@').substringUpTo('/');
		var options = {
			host: fullHost.substringUpTo(':'),
			port: fullHost.substringFrom(':'),
		};
		var socket = net.connect(options, function(error)
		{
			if (error)
			{
				return callback(error);
			}
			return callback(null, socket);
		});
	}

	self.query = function(query, params, callback)
	{
		if (typeof params == 'function')
		{
			callback = params;
			params = null;
		}
		connect(function(error, socket)
		{
			if (error)
			{
				return callback('Could not connect to  ' + address + ': ' + error);
			}
			var message = {
				query: query,
				params: params,
			};
			socket.write(JSON.stringify(message), function(error)
			{
				if (error)
				{
					return callback('Could not connect: ' + error);
				}
				socket.on('data', function(data)
				{
					socket.end();
					return callback(null, JSON.parse(data));
				});
				socket.on('error', function(error)
				{
					return callback('Could not receive data: ' + error);
				});
			});
		});
	};

	self.done = function()
	{
	};

	self.end = function()
	{
	};
};

function testRemoteClient(callback)
{
	var options = {port: TEST_PORT};
	server.start(options, function(error, testServer)
	{
		var client = new exports.RemoteClient(TEST_ADDRESS);
		client.query('select current_user', function(error)
		{
			testing.check(error, 'Could not run query to %s', TEST_ADDRESS, callback);
			client.end();
			testServer.close(function(error)
			{
				testing.check(error, 'Could not close server', callback);
				testing.success(callback);
			});
		});
	});
}

/**
 * Run package tests.
 */
exports.test = function(callback)
{
	var tests = [
		testRemoteClient,
	];
	testing.run(tests, callback);
};

// run tests if invoked directly
if (__filename == process.argv[1])
{
	exports.test(testing.show);
}

<commit_msg>Check user returned by remote client in test.<commit_after>'use strict';

/**
 * A remote client that sends request to a pooled-pg server.
 * (C) 2015 Alex Fernández.
 */

// requires
require('prototypes');
var net = require('net');
var server = require('./server.js');
var testing = require('testing');

// constants
var TEST_PORT = 5444;
var TEST_ADDRESS = 'pooled://test:test@localhost: ' + TEST_PORT +  '/test';

// globals
var clients = [];

exports.remoteConnect = function(address, callback)
{
	var client = new exports.RemoteClient(address);
	callback(null, client, client.done);
};

exports.end = function()
{
	clients.forEach(function(client)
	{
		client.end();
	});
};

exports.RemoteClient = function(address)
{
	// self-reference
	var self = this;

	// init
	clients.push(self);

	function connect(callback)
	{
		var fullHost = address.substringFrom('@').substringUpTo('/');
		var options = {
			host: fullHost.substringUpTo(':'),
			port: fullHost.substringFrom(':'),
		};
		var socket = net.connect(options, function(error)
		{
			if (error)
			{
				return callback(error);
			}
			return callback(null, socket);
		});
	}

	self.query = function(query, params, callback)
	{
		if (typeof params == 'function')
		{
			callback = params;
			params = null;
		}
		connect(function(error, socket)
		{
			if (error)
			{
				return callback('Could not connect to  ' + address + ': ' + error);
			}
			var message = {
				query: query,
				params: params,
			};
			socket.write(JSON.stringify(message), function(error)
			{
				if (error)
				{
					return callback('Could not connect: ' + error);
				}
				socket.on('data', function(data)
				{
					socket.end();
					return callback(null, JSON.parse(data));
				});
				socket.on('error', function(error)
				{
					return callback('Could not receive data: ' + error);
				});
			});
		});
	};

	self.done = function()
	{
	};

	self.end = function()
	{
	};
};

function testRemoteClient(callback)
{
	var options = {port: TEST_PORT};
	server.start(options, function(error, testServer)
	{
		var client = new exports.RemoteClient(TEST_ADDRESS);
		client.query('select current_user', function(error, result)
		{
			testing.check(error, 'Could not run query to %s', TEST_ADDRESS, callback);
			testing.assert(result, 'No result', callback);
			testing.assert(result.rowCount, 'No rows', callback);
			testing.assert(result.rows[0], 'No first row', callback);
			var user = result.rows[0].current_user;
			testing.assertEquals(user, 'test', 'Invalid user', callback);
			client.end();
			testServer.close(function(error)
			{
				testing.check(error, 'Could not close server', callback);
				testing.success(callback);
			});
		});
	});
}

/**
 * Run package tests.
 */
exports.test = function(callback)
{
	var tests = [
		testRemoteClient,
	];
	testing.run(tests, callback);
};

// run tests if invoked directly
if (__filename == process.argv[1])
{
	exports.test(testing.show);
}

<|endoftext|>


<commit_before>/**
 *  SERVER
 *
 *  This file should only run on your devbox, (IE, in the data center).
 *  If you are planning on remotely working (shelling into the box), then
 *  you shouldn't need this file at all
 */
var fs = require('fs-extra'),
    Server = require('../lib/ws-server'),
    util = require('../lib/util'),
    server = null;

function addFile(message) {
    fs.outputFile(message.filepath, message.contents);
}

function addDir(message) {
    fs.mkdirs(message.filepath);
}

function removePath(message) {
    fs.delete(message.filepath);
}

module.exports = function startRemote(cmd) {

	server = new Server({
        port: cmd.port,
        secret: cmd.secret,
        debug: cmd.debug
    });

    server.on('file-change', function(message) {
        if (cmd.debug) util.log('<', message.changeType, message.filepath);

        switch (message.changeType) {
            case 'add':
                addFile(message);
                break;
            case 'addDir':
                addDir(message);
                break;
            case 'change':
                addFile(message);
                break;
            case 'unlink':
                removePath(message);
                break;
            case 'unlinkDir':
                removePath(message);
                break;
            default:
                break;
        }
    });

    server.on('unauthorized', function() {
        util.log('Unauthorized connection. Stopping server.');
        process.exit();
    });

    server.on('connection-closed', function() {
        util.log('Connection closed. Stopping server.');
        process.exit();
    });

    server.on('ready', function() {
        util.log('Server is ready');
    });
};
<commit_msg>Debuggin'<commit_after>/**
 *  SERVER
 *
 *  This file should only run on your devbox, (IE, in the data center).
 *  If you are planning on remotely working (shelling into the box), then
 *  you shouldn't need this file at all
 */
var fs = require('fs-extra'),
    Server = require('../lib/ws-server'),
    util = require('../lib/util'),
    server = null;

function addFile(message) {
    fs.outputFile(message.filepath, message.contents);
}

function addDir(message) {
    fs.mkdirs(message.filepath);
}

function removePath(message) {
    fs.delete(message.filepath);
}

module.exports = function startRemote(cmd) {
    console.log(cmd);
	server = new Server({
        port: cmd.port,
        secret: cmd.secret,
        debug: cmd.debug
    });

    server.on('file-change', function(message) {
        if (cmd.debug) util.log('<', message.changeType, message.filepath);

        switch (message.changeType) {
            case 'add':
                addFile(message);
                break;
            case 'addDir':
                addDir(message);
                break;
            case 'change':
                addFile(message);
                break;
            case 'unlink':
                removePath(message);
                break;
            case 'unlinkDir':
                removePath(message);
                break;
            default:
                break;
        }
    });

    server.on('unauthorized', function() {
        util.log('Unauthorized connection. Stopping server.');
        process.exit();
    });

    server.on('connection-closed', function() {
        util.log('Connection closed. Stopping server.');
        process.exit();
    });

    server.on('ready', function() {
        util.log('Server is ready');
    });
};
<|endoftext|>