<commit_before>var EventEmitter = require('events').EventEmitter
  , gcr = new EventEmitter
  , log = require('npmlog')
  , fs = require('fs')
  , nconf = require('nconf')
  , mkdirp = require('mkdirp')
  , path = require('path')
  , home = process.env.HOME || process.env.USERPROFILE || '/root'
  , confFile = path.join(home, '.config', 'gcr.json')
  , slide = require('slide')
  , chain = slide.chain
  , which = require('which')

log.heading = 'gcr'

module.exports = gcr

gcr.root = path.dirname(confFile)
gcr.loaded = false
gcr.version = require('../package').version
gcr.key = path.join(home, '.ssh', 'gcr.pub')

gcr.utils = require('./utils')

gcr.load = function(opts, cb) {
  if ('function' === typeof opts) cb = opts, opts = {}
  if (gcr.loaded) return cb()
  mkdirp(gcr.root, function(err) {
    log.resume()
    if (err) {
      err.heading = '[mkdirp]'
      return cb(err)
    }
    nconf.file({ file: confFile })
    nconf.defaults(require('./config.default')(opts))
    if (opts.url) {
      nconf.set('url', opts.url)
    }
    if (opts.token) {
      nconf.set('token', opts.token)
    }
    if (opts.buildDir) {
      nconf.set('buildDir', opts.buildDir)
    }
    if (opts.npm) {
      nconf.set('npm', opts.npm)
    }
    if (opts.strictSSL) {
      nconf.set('strictSSL', opts.strictSSL)
    }
    if (opts.timeout) {
      nconf.set('timeout', opts.timeout)
    }
    if (!nconf.get('buildDir')) {
      nconf.set('buildDir', '/tmp/builds')
    }
    gcr.config = nconf
    chain([
        validateGit
      , validateSetup
      , saveConfig
    ], cb)
  })
}

function validateGit(cb) {
  if (nconf.get('git')) return cb()
  which('git', function(err, git) {
    if (err) {
      err.heading = '[which]'
      return cb(err)
    }
    nconf.set('git', git)
    cb()
  })
}

function validateSetup(cb) {
  mkdirp(gcr.config.get('buildDir'), function(err) {
    if (err) {
      err.heading = '[mkdirp]'
      return cb && cb(err)
    }

    fs.exists(gcr.key, function(e) {
      if (!e) {
        gcr.utils.genSSHKey(function(err) {
          if (err) {
            err.heading = '[ssh-keygen]'
            return cb && cb(err)
          }
          cb()
        })
      } else {
        cb()
      }
    })
  })
}

function saveConfig(cb) {
  nconf.save(function() {
    log.level = gcr.config.get('loglevel')
    log.heading = gcr.config.get('heading') || 'gcr'
    gcr.log = log
    gcr.loaded = true
    gcr.runner = require('./runner')()
    gcr.client = require('./client')()
    cb()
  })
}

gcr.help = [
    ''
  , 'gcr v'+gcr.version
  , ''
  , '   Usage:'
  , ''
  , '     gcr [options]'
  , ''
  , '   Options:'
  , ''
  , '     -h, --help                  Show help and usage'
  , '     -l, --loglevel <level>      Set log level'
  , '     -v, --version               Show version'
  , '     -u, --url <url>             Set CI Server URL'
  , '     -t, --token <token>         Set Registration Token'
  , '     -T, --timeout <number>      Set the timeout in seconds'
  , '     -b, --buildDir <dir>        Set the builds directory'
  , '     -s, --strictSSL             Strict SSL'
  , '     -n, --npm                   Run npm install/test if no commands '+
    'are present'
  , ''
].join('\n')
<commit_msg>Correctly check for strictSSL<commit_after>var EventEmitter = require('events').EventEmitter
  , gcr = new EventEmitter
  , log = require('npmlog')
  , fs = require('fs')
  , nconf = require('nconf')
  , mkdirp = require('mkdirp')
  , path = require('path')
  , home = process.env.HOME || process.env.USERPROFILE || '/root'
  , confFile = path.join(home, '.config', 'gcr.json')
  , slide = require('slide')
  , chain = slide.chain
  , which = require('which')

log.heading = 'gcr'

module.exports = gcr

gcr.root = path.dirname(confFile)
gcr.loaded = false
gcr.version = require('../package').version
gcr.key = path.join(home, '.ssh', 'gcr.pub')

gcr.utils = require('./utils')

gcr.load = function(opts, cb) {
  if ('function' === typeof opts) cb = opts, opts = {}
  if (gcr.loaded) return cb()
  mkdirp(gcr.root, function(err) {
    log.resume()
    if (err) {
      err.heading = '[mkdirp]'
      return cb(err)
    }
    nconf.file({ file: confFile })
    nconf.defaults(require('./config.default')(opts))
    if (opts.url) {
      nconf.set('url', opts.url)
    }
    if (opts.token) {
      nconf.set('token', opts.token)
    }
    if (opts.buildDir) {
      nconf.set('buildDir', opts.buildDir)
    }
    if (opts.npm) {
      nconf.set('npm', opts.npm)
    }
    if (opts.hasOwnProperty('strictSSL')) {
      nconf.set('strictSSL', opts.strictSSL)
    }
    if (opts.timeout) {
      nconf.set('timeout', opts.timeout)
    }
    if (!nconf.get('buildDir')) {
      nconf.set('buildDir', '/tmp/builds')
    }
    gcr.config = nconf
    chain([
        validateGit
      , validateSetup
      , saveConfig
    ], cb)
  })
}

function validateGit(cb) {
  if (nconf.get('git')) return cb()
  which('git', function(err, git) {
    if (err) {
      err.heading = '[which]'
      return cb(err)
    }
    nconf.set('git', git)
    cb()
  })
}

function validateSetup(cb) {
  mkdirp(gcr.config.get('buildDir'), function(err) {
    if (err) {
      err.heading = '[mkdirp]'
      return cb && cb(err)
    }

    fs.exists(gcr.key, function(e) {
      if (!e) {
        gcr.utils.genSSHKey(function(err) {
          if (err) {
            err.heading = '[ssh-keygen]'
            return cb && cb(err)
          }
          cb()
        })
      } else {
        cb()
      }
    })
  })
}

function saveConfig(cb) {
  nconf.save(function() {
    log.level = gcr.config.get('loglevel')
    log.heading = gcr.config.get('heading') || 'gcr'
    gcr.log = log
    gcr.loaded = true
    gcr.runner = require('./runner')()
    gcr.client = require('./client')()
    cb()
  })
}

gcr.help = [
    ''
  , 'gcr v'+gcr.version
  , ''
  , '   Usage:'
  , ''
  , '     gcr [options]'
  , ''
  , '   Options:'
  , ''
  , '     -h, --help                  Show help and usage'
  , '     -l, --loglevel <level>      Set log level'
  , '     -v, --version               Show version'
  , '     -u, --url <url>             Set CI Server URL'
  , '     -t, --token <token>         Set Registration Token'
  , '     -T, --timeout <number>      Set the timeout in seconds'
  , '     -b, --buildDir <dir>        Set the builds directory'
  , '     -s, --strictSSL             Strict SSL'
  , '     -n, --npm                   Run npm install/test if no commands '+
    'are present'
  , ''
].join('\n')
<|endoftext|>


<commit_before>var builder = require('focus').component.builder;
var React = require('react');
var assign = require('object-assign');
var isEmpty = require('lodash/lang/isEmpty');

// Common mixins.
var definitionMixin = require('../mixin/definition');
//var fieldComponentBehaviour = require('../mixin/field-component-behaviour');
var builtInComponents = require('../mixin/built-in-components');

//Form mixins.
var referenceBehaviour = require('./mixin/reference-behaviour');
var storeBehaviour = require('./mixin/store-behaviour');
var actionBehaviour = require('./mixin/action-behaviour');

/**
 * Mixin to create a block for the rendering.
 * @type {Object}
 */
var formMixin = {
  mixins: [definitionMixin, referenceBehaviour, storeBehaviour, actionBehaviour, builtInComponents],
  /** @inheritdoc */
  getDefaultProps: function getFormDefaultProps() {
    return {
      /**
       * Defines it the form can have  an edit mode.
       * @type {Boolean}
       */
      hasEdit: true,
      /**
       * Defines
       * @type {Boolean}
       */
      isEdit: false,
      /**
       * Style of the component.
       * @type {Object}
       */
      style: {}
    };
  },
  /** @inheritdoc */
  getInitialState: function getFormInitialState() {
    return {
      /**
       * Identifier of the entity.
       * @type {[type]}
       */
      id: this.props.id,
      isEdit: this.props.isEdit
    };
  },
  /**
   * Event handler for 'change' events coming from the stores
   */
  _onChange: function onFormStoreChangeHandler() {
    this.setState(this._getStateFromStores());
  },
  /** @inheritdoc */
  callMountedActions: function formCallMountedActions() {
    this._loadData();
    this._loadReference();
  },
  /** @inheritdoc */
  componentDidMount: function formDidMount() {
    //Build the definitions.
    if (this.registerListeners) {
      this.registerListeners();
    }
    if (this.callMountedActions) {
      this.callMountedActions();
    }
  },
  /** @inheritdoc */
  componentWillUnmount: function formWillMount() {
    if (this.unregisterListeners) {
      this.unregisterListeners();
    }
  },

  /**
   * Validate the form information by information.
   * In case of errors the state is modified.
   * @returns {boolean} - A boolean ttue if the
   */
  validate: function validateForm() {
    var validationMap = {};
    for (var inptKey in this.refs) {
      var validationRes = this.refs[inptKey].validate();
      if(validationRes !== undefined){
        assign(validationMap, {
          [inptKey]: validationRes
        });
      }
    }
    if(isEmpty(validationMap)){
      return true;
    }

    return false;
  },
  _editClass: function(){
    if(this.editClass){return this.editClass(); }
    return `form-${this.state.isEdit ? 'edit' : 'consult'}`;
  },
  _className: function formClassName() {
    return `form-horizontal ${this.props.style.className} ${this._editClass()}`;
  },
  _renderActions: function renderActions(){
    if(this.renderActions){return this.renderActions(); }
    if(this.state.isEdit){
      return this._renderEditActions();
    }
    return this._renderConsultActions();
  },
  _renderEditActions: function _renderEditActions(){
    if(this.renderEditActions){return this.renderEditActions(); }
    return (

        {this.buttonCancel()}
        {this.buttonSave()}

    );
  },
  _renderConsultActions: function _renderConsultActions(){
    if(this.renderConsultActions){return this.renderConsultActions(); }
    return this.buttonEdit();
  },
  /**
   * Handle the form submission.
   * @param {Event} e - React sanityze event from the form submit.
   */
  _handleSubmitForm: function handleSumbitForm(e) {
    e.preventDefault();
    if(this.validate()){
      this.action.save(this._getEntity());
    }
    //return false;
  },
  /** @inheritdoc */
  render: function renderForm() {
    return (
      <form
        onSubmit={this._handleSubmitForm}
        className={this._className()}
      >
        <fieldset>
          {this.renderContent()}
        </fieldset>
      </form>
    );
  }
};

module.exports = builder(formMixin);
<commit_msg>[form] Validation only if there is a validate method<commit_after>var builder = require('focus').component.builder;
var React = require('react');
var assign = require('object-assign');
var {isEmpty, isFunction} = require('lodash/lang');

// Common mixins.
var definitionMixin = require('../mixin/definition');
//var fieldComponentBehaviour = require('../mixin/field-component-behaviour');
var builtInComponents = require('../mixin/built-in-components');

//Form mixins.
var referenceBehaviour = require('./mixin/reference-behaviour');
var storeBehaviour = require('./mixin/store-behaviour');
var actionBehaviour = require('./mixin/action-behaviour');

/**
 * Mixin to create a block for the rendering.
 * @type {Object}
 */
var formMixin = {
  mixins: [definitionMixin, referenceBehaviour, storeBehaviour, actionBehaviour, builtInComponents],
  /** @inheritdoc */
  getDefaultProps: function getFormDefaultProps() {
    return {
      /**
       * Defines it the form can have  an edit mode.
       * @type {Boolean}
       */
      hasEdit: true,
      /**
       * Defines
       * @type {Boolean}
       */
      isEdit: false,
      /**
       * Style of the component.
       * @type {Object}
       */
      style: {}
    };
  },
  /** @inheritdoc */
  getInitialState: function getFormInitialState() {
    return {
      /**
       * Identifier of the entity.
       * @type {[type]}
       */
      id: this.props.id,
      isEdit: this.props.isEdit
    };
  },
  /**
   * Event handler for 'change' events coming from the stores
   */
  _onChange: function onFormStoreChangeHandler() {
    this.setState(this._getStateFromStores());
  },
  /** @inheritdoc */
  callMountedActions: function formCallMountedActions() {
    this._loadData();
    this._loadReference();
  },
  /** @inheritdoc */
  componentDidMount: function formDidMount() {
    //Build the definitions.
    if (this.registerListeners) {
      this.registerListeners();
    }
    if (this.callMountedActions) {
      this.callMountedActions();
    }
  },
  /** @inheritdoc */
  componentWillUnmount: function formWillMount() {
    if (this.unregisterListeners) {
      this.unregisterListeners();
    }
  },

  /**
   * Validate the form information by information.
   * In case of errors the state is modified.
   * @returns {boolean} - A boolean ttue if the
   */
  validate: function validateForm() {
    var validationMap = {};
    for (var inptKey in this.refs) {
      //validate only the reference elements which have valide function
      // todo: @pierr see if it is sufficient
      if(isFunction(this.refs[inptKey].validate)){
        var validationRes = this.refs[inptKey].validate();
        if(validationRes !== undefined){
          assign(validationMap, {
            [inptKey]: validationRes
          });
        }
      }

    }
    if(isEmpty(validationMap)){
      return true;
    }

    return false;
  },
  _editClass: function(){
    if(this.editClass){return this.editClass(); }
    return `form-${this.state.isEdit ? 'edit' : 'consult'}`;
  },
  _className: function formClassName() {
    return `form-horizontal ${this.props.style.className} ${this._editClass()}`;
  },
  _renderActions: function renderActions(){
    if(this.renderActions){return this.renderActions(); }
    if(this.state.isEdit){
      return this._renderEditActions();
    }
    return this._renderConsultActions();
  },
  _renderEditActions: function _renderEditActions(){
    if(this.renderEditActions){return this.renderEditActions(); }
    return (

        {this.buttonCancel()}
        {this.buttonSave()}

    );
  },
  _renderConsultActions: function _renderConsultActions(){
    if(this.renderConsultActions){return this.renderConsultActions(); }
    return this.buttonEdit();
  },
  /**
   * Handle the form submission.
   * @param {Event} e - React sanityze event from the form submit.
   */
  _handleSubmitForm: function handleSumbitForm(e) {
    e.preventDefault();
    if(this.validate()){
      this.action.save(this._getEntity());
    }
    //return false;
  },
  /** @inheritdoc */
  render: function renderForm() {
    return (
      <form
        onSubmit={this._handleSubmitForm}
        className={this._className()}
      >
        <fieldset>
          {this.renderContent()}
        </fieldset>
      </form>
    );
  }
};

module.exports = builder(formMixin);
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017  Anthony DeDominic <adedomin@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

var Irc = require('irc-framework'),
    colors = require('irc-colors'),
    reladate = require('relative-date'),
    config = require(process.env.CONFIG_PATH).irc,
    mooseLock = false,
    moosedb,
    logger

var mooseColor = {
    0: colors.white,
    1: colors.black,
    2: colors.navy,
    3: colors.green,
    4: colors.red,
    5: colors.brown,
    6: colors.purple,
    7: colors.olive,
    8: colors.yellow,
    9: colors.lime,
    a: colors.teal,
    b: colors.cyan,
    c: colors.blue,
    d: colors.pink,
    e: colors.gray,
    f: colors.silver,
}

var mooseShade = {
    0: '░',
    1: '▒',
    2: '▓',
    3: '█',
    4: '▓',
    5: '▒',
    6: '░',
}

function mooseLine(line, shade) {
    return line.split('').map((char, ind) => {
        if (char == 't')
            return ' '
        if (!shade || shade.length < 1 || +shade[ind] == 3)
            return mooseColor[char](mooseShade['3'])
        else if (+shade[ind] == 3) {
            return mooseColor[char](mooseShade['3'])
        }
        else if (+shade[ind] < 3) {
            return mooseColor[char].bgwhite(mooseShade[shade[ind]])
        }
        else {
            return mooseColor[char].bgblack(mooseShade[shade[ind]])
        }
    }).join('')
}

function mooseTrimTransparent(orlines) {
    // copy arr
    var lines = orlines.slice()
    // top down
    var tline = /^t*$/

    var filtered = false
    // top down
    lines = lines.filter(line => {
        if (tline.test(line) && !filtered)
            return false
        filtered = true
        return true
    })

    filtered = false
    // bottom up
    lines = lines.slice().reverse().filter(line => {
        if (tline.test(line) && !filtered)
            return false

        filtered = true
        return true
    }).reverse()

    // empty moose
    if (lines.length < 1)
        return lines

    // left to right
    var substr = 0
    for (var i=0; i<lines[0].length; i++) {
        if (lines.reduce((acc, line) => {
            return line[i] == 't' && acc
        }, true)) {
            substr++
        }
        else {
            break
        }
    }

    // trim all moose by substr
    if (substr > 0) {
        lines = lines.map(line => {
            return line.substring(substr)
        })
    }

    // right left
    substr = 0
    for (i=lines[0].length-1; i>-1; i--) {
        if (lines.reduce((acc, line) => {
            return line[i] == 't' && acc
        }, true)) {
            substr++
        }
        else {
            break
        }
    }

    if (substr > 0) {
        lines = lines.map(line => {
            return line.substring(0, line.length - substr)
        })
    }

    return lines
}

function sendMoose(moose, event, unknownName) {
    var curr = 0,
        image = mooseTrimTransparent(moose.image.split('\n')),
        shade
    if (moose.shaded)
        shade = mooseTrimTransparent(moose.shade.split('\n'))
    else
        shade = []

    function next() {
        if (!(curr < image.length)) {
            if (unknownName) {
                event.reply(
                    `${colors.bold(moose.name)} - Created ${reladate(moose.created)}`
                )
            }
            else {
                event.reply(
                    `Created ${reladate(moose.created)}`
                )
            }
            setTimeout(() => mooseLock = false,
                config.moose_delay || 5000
            )
            return
        }
        event.reply(mooseLine(image[curr], shade[curr]))
        curr++
        setTimeout(next.bind(this), config.send_delay || 350)
    }
    next()
}

function getLatest(event) {
    sendMoose(moosedb.latest.res[0], event, true)
}

function getRandom(event) {
    moosedb.random((err, rand) => {
        if (err || !rand[0]) return event.reply('Unknown Error with Random')
        sendMoose(rand[0], event, true)
    })
}

function getMoose(query, event) {
    moosedb.findOne({ name: query }, (err, moose) => {
        if (err || !moose)
            return event.reply(
                `No Such Moose: ${colors.bold(query)}`
            )
        sendMoose(moose, event)
    })
}

function searchNameRegexp(name) {
    return new RegExp(name.replace(
        /[|\\{()[^$+*?.-]/g,
        '\\$&'
    ), 'i')
}

function getSearch(query, event) {
    if (!query)
        return event.reply('usage: --search query')

    moosedb.find({
        name: { $regex: searchNameRegexp(query)},
    }).sort({ created: -1 })
        .limit(12)
        .map(meese => colors.bold(meese.name))
        .exec((err, meese) => {
            if (err || !meese || meese.length < 1)
                meese = ['No Moose Found For', colors.bold(query)]
            event.reply(meese.join(' - '))
        })
}

module.exports = (moosedb_, logger_) => {
    if (!config || config.disabled) return

    moosedb = moosedb_
    logger = logger_

    var irc = new Irc.Client()

    irc.on('error', (msg) => {
        logger.error('IRC error', { err: msg.toString() })
    })

    irc.on('registered', () => {
        if (config.nickserv_pass)
            irc.say('NickServ', `IDENTIFY ${config.nickserv_pass}`)

        config.channels.forEach(channel => irc.join(channel))
    })

    irc.matchMessage(/^[.!](bots|help)/, (event) => {
        event.reply(
            `neomoose [JavaScript|NodeJS] :: Make moose @ ${config.moose_url || 'https://moose.ghetty.space'} :: See .moose --help for usage`
        )
    })

    irc.matchMessage(/^[.!]*moose/, (event) => {
        if (mooseLock)
            return irc.notice(event.nick, 'Please Wait for the Current Moose to finish')

        var parse = event.message
            .match(/^[.!]*moose (-[^ ]*)? ?(.*)/)
        if (!parse) parse = { arg: '-h', query: null }

        var arg = parse[1],
            query = parse[2]

        if (arg == '--latest' ||
            arg == '-l' ||
            query == 'latest'
        ) {
            mooseLock = true
            getLatest(event)
        }
        else if (arg == '--random' ||
            arg == '-r' ||
            query == 'random'
        ) {
            mooseLock = true
            getRandom(event)
        }
        else if (arg == '--search' || arg == '-s') {
            getSearch(query, event)
        }
        else if (arg == '--') {
            mooseLock = true
            getMoose(query, event)
        }
        else if (arg == '--help' || arg == '-h' || !query) {
            event.reply('usage: [.!]*moose [--latest|--random|--search|--] moosename')
            event.reply(`Make moose @ ${config.moose_url || 'https://moose.ghetty.space'}`)
        }
        else if (arg) {
            event.reply(`invalid argument: ${arg}`)
            event.reply('usage: [.!]*moose [--latest|--random] moosename')
        }
        else {
            mooseLock = true
            getMoose(query, event)
        }
    })

    irc.connect({
        host: config.server,
        nick: config.nick,
        port: config.port,
        tls: config.tls,
    })
}
<commit_msg>changed .help<commit_after>/*
 * Copyright (C) 2017  Anthony DeDominic <adedomin@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

var Irc = require('irc-framework'),
    colors = require('irc-colors'),
    reladate = require('relative-date'),
    config = require(process.env.CONFIG_PATH).irc,
    mooseLock = false,
    moosedb,
    logger

var mooseColor = {
    0: colors.white,
    1: colors.black,
    2: colors.navy,
    3: colors.green,
    4: colors.red,
    5: colors.brown,
    6: colors.purple,
    7: colors.olive,
    8: colors.yellow,
    9: colors.lime,
    a: colors.teal,
    b: colors.cyan,
    c: colors.blue,
    d: colors.pink,
    e: colors.gray,
    f: colors.silver,
}

var mooseShade = {
    0: '░',
    1: '▒',
    2: '▓',
    3: '█',
    4: '▓',
    5: '▒',
    6: '░',
}

function mooseLine(line, shade) {
    return line.split('').map((char, ind) => {
        if (char == 't')
            return ' '
        if (!shade || shade.length < 1 || +shade[ind] == 3)
            return mooseColor[char](mooseShade['3'])
        else if (+shade[ind] == 3) {
            return mooseColor[char](mooseShade['3'])
        }
        else if (+shade[ind] < 3) {
            return mooseColor[char].bgwhite(mooseShade[shade[ind]])
        }
        else {
            return mooseColor[char].bgblack(mooseShade[shade[ind]])
        }
    }).join('')
}

function mooseTrimTransparent(orlines) {
    // copy arr
    var lines = orlines.slice()
    // top down
    var tline = /^t*$/

    var filtered = false
    // top down
    lines = lines.filter(line => {
        if (tline.test(line) && !filtered)
            return false
        filtered = true
        return true
    })

    filtered = false
    // bottom up
    lines = lines.slice().reverse().filter(line => {
        if (tline.test(line) && !filtered)
            return false

        filtered = true
        return true
    }).reverse()

    // empty moose
    if (lines.length < 1)
        return lines

    // left to right
    var substr = 0
    for (var i=0; i<lines[0].length; i++) {
        if (lines.reduce((acc, line) => {
            return line[i] == 't' && acc
        }, true)) {
            substr++
        }
        else {
            break
        }
    }

    // trim all moose by substr
    if (substr > 0) {
        lines = lines.map(line => {
            return line.substring(substr)
        })
    }

    // right left
    substr = 0
    for (i=lines[0].length-1; i>-1; i--) {
        if (lines.reduce((acc, line) => {
            return line[i] == 't' && acc
        }, true)) {
            substr++
        }
        else {
            break
        }
    }

    if (substr > 0) {
        lines = lines.map(line => {
            return line.substring(0, line.length - substr)
        })
    }

    return lines
}

function sendMoose(moose, event, unknownName) {
    var curr = 0,
        image = mooseTrimTransparent(moose.image.split('\n')),
        shade
    if (moose.shaded)
        shade = mooseTrimTransparent(moose.shade.split('\n'))
    else
        shade = []

    function next() {
        if (!(curr < image.length)) {
            if (unknownName) {
                event.reply(
                    `${colors.bold(moose.name)} - Created ${reladate(moose.created)}`
                )
            }
            else {
                event.reply(
                    `Created ${reladate(moose.created)}`
                )
            }
            setTimeout(() => mooseLock = false,
                config.moose_delay || 5000
            )
            return
        }
        event.reply(mooseLine(image[curr], shade[curr]))
        curr++
        setTimeout(next.bind(this), config.send_delay || 350)
    }
    next()
}

function getLatest(event) {
    sendMoose(moosedb.latest.res[0], event, true)
}

function getRandom(event) {
    moosedb.random((err, rand) => {
        if (err || !rand[0]) return event.reply('Unknown Error with Random')
        sendMoose(rand[0], event, true)
    })
}

function getMoose(query, event) {
    moosedb.findOne({ name: query }, (err, moose) => {
        if (err || !moose)
            return event.reply(
                `No Such Moose: ${colors.bold(query)}`
            )
        sendMoose(moose, event)
    })
}

function searchNameRegexp(name) {
    return new RegExp(name.replace(
        /[|\\{()[^$+*?.-]/g,
        '\\$&'
    ), 'i')
}

function getSearch(query, event) {
    if (!query)
        return event.reply('usage: --search query')

    moosedb.find({
        name: { $regex: searchNameRegexp(query)},
    }).sort({ created: -1 })
        .limit(12)
        .map(meese => colors.bold(meese.name))
        .exec((err, meese) => {
            if (err || !meese || meese.length < 1)
                meese = ['No Moose Found For', colors.bold(query)]
            event.reply(meese.join(' - '))
        })
}

module.exports = (moosedb_, logger_) => {
    if (!config || config.disabled) return

    moosedb = moosedb_
    logger = logger_

    var irc = new Irc.Client()

    irc.on('error', (msg) => {
        logger.error('IRC error', { err: msg.toString() })
    })

    irc.on('registered', () => {
        if (config.nickserv_pass)
            irc.say('NickServ', `IDENTIFY ${config.nickserv_pass}`)

        config.channels.forEach(channel => irc.join(channel))
    })

    irc.matchMessage(/^[.!](bots|help)/, (event) => {
        event.reply(
            `NeoMoose [JavaScript|NodeJS] :: Make moose @ ${config.moose_url || 'https://moose.ghetty.space'} :: See .moose --help for usage`
        )
    })

    irc.matchMessage(/^[.!]*moose/, (event) => {
        if (mooseLock)
            return irc.notice(event.nick, 'Please Wait for the Current Moose to finish')

        var parse = event.message
            .match(/^[.!]*moose (-[^ ]*)? ?(.*)/)
        if (!parse) parse = { arg: '-h', query: null }

        var arg = parse[1],
            query = parse[2]

        if (arg == '--latest' ||
            arg == '-l' ||
            query == 'latest'
        ) {
            mooseLock = true
            getLatest(event)
        }
        else if (arg == '--random' ||
            arg == '-r' ||
            query == 'random'
        ) {
            mooseLock = true
            getRandom(event)
        }
        else if (arg == '--search' || arg == '-s') {
            getSearch(query, event)
        }
        else if (arg == '--') {
            mooseLock = true
            getMoose(query, event)
        }
        else if (arg == '--help' || arg == '-h' || !query) {
            event.reply('usage: [.!]*moose [--latest|--random|--search|--] moosename')
            event.reply(`Make moose @ ${config.moose_url || 'https://moose.ghetty.space'}`)
        }
        else if (arg) {
            event.reply(`invalid argument: ${arg}`)
            event.reply('usage: [.!]*moose [--latest|--random] moosename')
        }
        else {
            mooseLock = true
            getMoose(query, event)
        }
    })

    irc.connect({
        host: config.server,
        nick: config.nick,
        port: config.port,
        tls: config.tls,
    })
}
<|endoftext|>


<commit_before>/*global $: false, kanso: true */

/**
 * Contains functions for querying and storing data in CouchDB.
 */

/**
 * Module dependencies
 */

var utils = require('./utils'),
    settings = require('./settings');

var session = null;
// avoid making a circular require in CouchDB
if (utils.isBrowser) {
    session = require('./session');
}

/**
 * When a db call results in an unauthorized response, the user's session is
 * checked to see if their session has timed out or they've logged out in
 * another screen.
 *
 * This check is throttled to once per second, to avoid flooding the server if
 * multiple requests are made with incorrect permissions.
 */

var last_session_check = 0;

/**
 * Taken from jQuery 1.4.4 so we can support more recent versions of jQuery.
 */

var httpData = function (xhr, type, s) {
    var ct = xhr.getResponseHeader("content-type") || "",
        xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
        data = xml ? xhr.responseXML : xhr.responseText;

    if (xml && data.documentElement.nodeName === "parsererror") {
        $.error("parsererror");
    }
    if (s && s.dataFilter) {
        data = s.dataFilter(data, type);
    }
    if (typeof data === "string") {
        if (type === "json" || !type && ct.indexOf("json") >= 0) {
            data = $.parseJSON(data);
        }
        else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
            $.globalEval(data);
        }
    }
    return data;
};

/**
 * Returns a function for handling ajax responsed from jquery and calls
 * the callback with the data or appropriate error.
 *
 * @param {Function} callback
 * @api private
 */

function onComplete(callback) {
    return function (req) {
        var resp;
        var ctype = req.getResponseHeader('Content-Type');
        if (ctype === 'application/json' || ctype === 'text/json') {
            try {
                resp = httpData(req, "json");
            }
            catch (e) {
                return callback(e);
            }
        }
        else {
            resp = req.responseText;
        }
        if (req.status === 401) {
            // returned 'Unauthorized', check the user's session if it's not
            // been checked on an 'Unauthorized' repsonse in the last second
            if (session && last_session_check < new Date().getTime() - 1000) {
                session.info();
            }
        }
        if (req.status === 200 || req.status === 201 || req.status === 202) {
            callback(null, resp);
        }
        else if (resp.error) {
            var err = new Error(resp.reason || resp.error);
            err.error = resp.error;
            err.reason = resp.reason;
            err.status = req.status;
            callback(err);
        }
        else {
            // TODO: map status code to meaningful error message
            callback(new Error('Returned status code: ' + req.status));
        }
    };
}

/**
 * Encodes a document id or view, list or show name.
 *
 * @param {String} str
 * @return {String}
 * @api public
 */

exports.encode = function (str) {
    return encodeURIComponent(str).replace(/^_design%2F/, '_design/');
};

/**
 * Make a request, with some default settings and proper callback
 * handling. Used behind-the-scenes by most other DB module functions.
 *
 * @param {Object} options
 * @param {Function} callback
 */

exports.request = function (options, callback) {
    options.complete = onComplete(callback);
    options.dataType = 'json';
    $.ajax(options);
};

/**
 * Fetches a rewrite from the database the app is running on. Results
 * are passed to the callback, with the first argument of the callback
 * reserved for any exceptions that occurred (node.js style).
 *
 * @param {String} path
 * @param {Object} q (optional)
 * @param {Function} callback
 */

exports.getRewrite = function (path, /*optional*/q, callback) {
    if (!utils.isBrowser) {
        throw new Error('getRewrite cannot be called server-side');
    }
    if (!callback) {
        callback = q;
        q = {};
    }
    // prepend forward-slash if missing
    path = (path[0] === '/') ? path: '/' + path;

    var base = utils.getBaseURL();
    var name = exports.encode(settings.name);
    var req = {
        url: base + '/_db/_design/' + name + '/_rewrite' + path,
        data: exports.stringifyQuery(q)
    };
    exports.request(req, callback);
};

/**
 * Fetches a document from the database the app is running on. Results are
 * passed to the callback, with the first argument of the callback reserved
 * for any exceptions that occurred (node.js style).
 *
 * @param {String} id
 * @param {Object} q (optional)
 * @param {Function} callback
 */

exports.getDoc = function (id, /*optional*/q, callback) {
    if (!utils.isBrowser) {
        throw new Error('getDoc cannot be called server-side');
    }
    if (!callback) {
        callback = q;
        q = {};
    }
    var req = {
        url: utils.getBaseURL() + '/_db/' + exports.encode(id),
        data: exports.stringifyQuery(q)
    };
    exports.request(req, callback);
};

/**
 * Saves a document to the database the app is running on. Results are
 * passed to the callback, with the first argument of the callback reserved
 * for any exceptions that occurred (node.js style).
 *
 * @param {Object} doc
 * @param {Function} callback
 */

exports.saveDoc = function (doc, callback) {
    if (!utils.isBrowser) {
        throw new Error('saveDoc cannot be called server-side');
    }
    var method, url = utils.getBaseURL() + '/_db';
    if (doc._id === undefined) {
        method = "POST";
    }
    else {
        method = "PUT";
        url += '/' + exports.encode(doc._id);
    }
    var req = {
        type: method,
        url: url,
        data: JSON.stringify(doc),
        processData: false,
        contentType: 'application/json'
    };
    exports.request(req, callback);
};

/**
 * Deletes a document from the database the app is running on. Results are
 * passed to the callback, with the first argument of the callback reserved
 * for any exceptions that occurred (node.js style).
 *
 * @param {Object} doc
 * @param {Function} callback
 */

exports.removeDoc = function (doc, callback) {
    if (!utils.isBrowser) {
        throw new Error('removeDoc cannot be called server-side');
    }
    var url = utils.getBaseURL() + '/_db/' +
        exports.encode(doc._id) +
        '?rev=' + exports.encode(doc._rev);

    exports.request({type: 'DELETE', url: url}, callback);
};

/**
 * Fetches a view from the database the app is running on. Results are
 * passed to the callback, with the first argument of the callback reserved
 * for any exceptions that occurred (node.js style).
 *
 * @param {String} view
 * @param {Object} q (optional)
 * @param {Function} callback
 */

exports.getView = function (view, /*optional*/q, callback) {
    if (!utils.isBrowser) {
        throw new Error('getView cannot be called server-side');
    }
    if (!callback) {
        callback = q;
        q = {};
    }
    var base = utils.getBaseURL();
    var name = exports.encode(settings.name);
    var viewname = exports.encode(view);
    var req = {
        url: base + '/_db/_design/' + name + '/_view/' + viewname,
        data: exports.stringifyQuery(q)
    };
    exports.request(req, callback);
};

/**
 * Transforms and fetches a view through a list from the database the app
 * is running on. Results are passed to the callback, with the first
 * argument of the callback reserved for any exceptions that occurred
 * (node.js style).
 *
 * @param {String} list
 * @param {String} view
 * @param {Object} q (optional)
 * @param {Function} callback
 */

// TODO: run list function client-side?
exports.getList = function (list, view, /*optional*/q, callback) {
    if (!utils.isBrowser) {
        throw new Error('getList cannot be called server-side');
    }
    if (!callback) {
        callback = q;
        q = {};
    }
    var base = utils.getBaseURL();
    var name = exports.encode(settings.name);
    var listname = exports.encode(list);
    var viewname = exports.encode(view);
    var req = {
        url: base + '/_db/_design/' + name + '/_list/' + listname +
             '/' + viewname,
        data: exports.stringifyQuery(q)
    };
    exports.request(req, callback);
};

/**
 * Transforms and fetches a document through a show from the database the app
 * is running on. Results are passed to the callback, with the first
 * argument of the callback reserved for any exceptions that occurred
 * (node.js style).
 *
 * @param {String} show
 * @param {String} docid
 * @param {Object} q (optional)
 * @param {Function} callback
 */

// TODO: run show function client-side?
exports.getShow = function (show, docid, /*optional*/q, callback) {
    if (!utils.isBrowser) {
        throw new Error('getShow cannot be called server-side');
    }
    if (!callback) {
        callback = q;
        q = {};
    }
    var base = utils.getBaseURL();
    var name = exports.encode(settings.name);
    var showname = exports.encode(show);
    var show_url = base + '/_db/_design/' + name + '/_show/' + showname;
    var req = {
        url: show_url + (docid ? '/' + exports.encode(docid): ''),
        data: exports.stringifyQuery(q)
    };
    exports.request(req, callback);
};

/**
 * Get all documents (including design docs).
 *
 * @param {Object} q (optional)
 * @param {Function} callback
 * @api public
 */

exports.all = function (/*optional*/q, callback) {
    if (!utils.isBrowser) {
        throw new Error('all cannot be called server-side');
    }
    if (!callback) {
        callback = q;
        q = {};
    }
    var base = utils.getBaseURL();
    var req = {
        url: base + '/_db/_all_docs',
        data: exports.stringifyQuery(q)
    };
    exports.request(req, callback);
};

/**
 * Properly encodes query parameters to CouchDB views etc. Handle complex
 * keys and other non-string parameters by passing through JSON.stringify.
 * Returns a shallow-copied clone of the original query after complex values
 * have been stringified.
 *
 * @param {Object} query
 * @returns {Object}
 */

exports.stringifyQuery = function (query) {
    var q = {};
    for (var k in query) {
        if (typeof query[k] !== 'string') {
            q[k] = JSON.stringify(query[k]);
        }
        else {
            q[k] = query[k];
        }
    }
    return q;
};

/**
 * Returns a new UUID generated by CouchDB. Its possible to cache
 * multiple UUIDs for later use, to avoid making too many requests.
 *
 * @param {Number} cacheNum (optional, default: 1)
 * @param {Function} callback
 * @api public
 */

var uuidCache = [];

exports.newUUID = function (cacheNum, callback) {
    if (!utils.isBrowser) {
        throw new Error('newUUID cannot be called server-side');
    }
    if (!callback) {
        callback = cacheNum;
        cacheNum = 1;
    }
    if (uuidCache.length) {
        return callback(null, uuidCache.shift());
    }
    var base = utils.getBaseURL();
    var req = {
        url: '/_uuids',
        data: {count: cacheNum}
    };
    exports.request(req, function (err, resp) {
        if (err) {
            return callback(err);
        }
        uuidCache = resp.uuids;
        callback(null, uuidCache.shift());
    });
};
<commit_msg>update some db module function to expect JSON and return an error if another mime-type is returned<commit_after>/*global $: false, kanso: true */

/**
 * Contains functions for querying and storing data in CouchDB.
 */

/**
 * Module dependencies
 */

var utils = require('./utils'),
    settings = require('./settings');

var session = null;
// avoid making a circular require in CouchDB
if (utils.isBrowser) {
    session = require('./session');
}

/**
 * When a db call results in an unauthorized response, the user's session is
 * checked to see if their session has timed out or they've logged out in
 * another screen.
 *
 * This check is throttled to once per second, to avoid flooding the server if
 * multiple requests are made with incorrect permissions.
 */

var last_session_check = 0;

/**
 * Taken from jQuery 1.4.4 so we can support more recent versions of jQuery.
 */

var httpData = function (xhr, type, s) {
    var ct = xhr.getResponseHeader("content-type") || "",
        xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
        data = xml ? xhr.responseXML : xhr.responseText;

    if (xml && data.documentElement.nodeName === "parsererror") {
        $.error("parsererror");
    }
    if (s && s.dataFilter) {
        data = s.dataFilter(data, type);
    }
    if (typeof data === "string") {
        if (type === "json" || !type && ct.indexOf("json") >= 0) {
            data = $.parseJSON(data);
        }
        else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
            $.globalEval(data);
        }
    }
    return data;
};

/**
 * Returns a function for handling ajax responsed from jquery and calls
 * the callback with the data or appropriate error.
 *
 * @param {Function} callback
 * @api private
 */

function onComplete(options, callback) {
    return function (req) {
        var resp;
        var ctype = req.getResponseHeader('Content-Type');
        if (ctype === 'application/json' || ctype === 'text/json') {
            try {
                resp = httpData(req, "json");
            }
            catch (e) {
                return callback(e);
            }
        }
        else {
            if (options.expect_json) {
                return callback(
                    new Error('Expected JSON response, got ' + ctype)
                );
            }
            resp = req.responseText;
        }
        if (req.status === 401) {
            // returned 'Unauthorized', check the user's session if it's not
            // been checked on an 'Unauthorized' repsonse in the last second
            if (session && last_session_check < new Date().getTime() - 1000) {
                session.info();
            }
        }
        if (req.status === 200 || req.status === 201 || req.status === 202) {
            callback(null, resp);
        }
        else if (resp.error) {
            var err = new Error(resp.reason || resp.error);
            err.error = resp.error;
            err.reason = resp.reason;
            err.status = req.status;
            callback(err);
        }
        else {
            // TODO: map status code to meaningful error message
            callback(new Error('Returned status code: ' + req.status));
        }
    };
}

/**
 * Encodes a document id or view, list or show name.
 *
 * @param {String} str
 * @return {String}
 * @api public
 */

exports.encode = function (str) {
    return encodeURIComponent(str).replace(/^_design%2F/, '_design/');
};

/**
 * Make a request, with some default settings and proper callback
 * handling. Used behind-the-scenes by most other DB module functions.
 *
 * @param {Object} options
 * @param {Function} callback
 */

exports.request = function (options, callback) {
    options.complete = onComplete(options, callback);
    options.dataType = 'json';
    $.ajax(options);
};

/**
 * Fetches a rewrite from the database the app is running on. Results
 * are passed to the callback, with the first argument of the callback
 * reserved for any exceptions that occurred (node.js style).
 *
 * @param {String} path
 * @param {Object} q (optional)
 * @param {Function} callback
 */

exports.getRewrite = function (path, /*optional*/q, callback) {
    if (!utils.isBrowser) {
        throw new Error('getRewrite cannot be called server-side');
    }
    if (!callback) {
        callback = q;
        q = {};
    }
    // prepend forward-slash if missing
    path = (path[0] === '/') ? path: '/' + path;

    var base = utils.getBaseURL();
    var name = exports.encode(settings.name);
    var req = {
        url: base + '/_db/_design/' + name + '/_rewrite' + path,
        data: exports.stringifyQuery(q)
    };
    exports.request(req, callback);
};

/**
 * Fetches a document from the database the app is running on. Results are
 * passed to the callback, with the first argument of the callback reserved
 * for any exceptions that occurred (node.js style).
 *
 * @param {String} id
 * @param {Object} q (optional)
 * @param {Function} callback
 */

exports.getDoc = function (id, /*optional*/q, callback) {
    if (!utils.isBrowser) {
        throw new Error('getDoc cannot be called server-side');
    }
    if (!callback) {
        callback = q;
        q = {};
    }
    var req = {
        url: utils.getBaseURL() + '/_db/' + exports.encode(id),
        data: exports.stringifyQuery(q),
        expect_json: true
    };
    exports.request(req, callback);
};

/**
 * Saves a document to the database the app is running on. Results are
 * passed to the callback, with the first argument of the callback reserved
 * for any exceptions that occurred (node.js style).
 *
 * @param {Object} doc
 * @param {Function} callback
 */

exports.saveDoc = function (doc, callback) {
    if (!utils.isBrowser) {
        throw new Error('saveDoc cannot be called server-side');
    }
    var method, url = utils.getBaseURL() + '/_db';
    if (doc._id === undefined) {
        method = "POST";
    }
    else {
        method = "PUT";
        url += '/' + exports.encode(doc._id);
    }
    var req = {
        type: method,
        url: url,
        data: JSON.stringify(doc),
        processData: false,
        contentType: 'application/json',
        expect_json: true
    };
    exports.request(req, callback);
};

/**
 * Deletes a document from the database the app is running on. Results are
 * passed to the callback, with the first argument of the callback reserved
 * for any exceptions that occurred (node.js style).
 *
 * @param {Object} doc
 * @param {Function} callback
 */

exports.removeDoc = function (doc, callback) {
    if (!utils.isBrowser) {
        throw new Error('removeDoc cannot be called server-side');
    }
    var url = utils.getBaseURL() + '/_db/' +
        exports.encode(doc._id) +
        '?rev=' + exports.encode(doc._rev);

    exports.request({type: 'DELETE', url: url}, callback);
};

/**
 * Fetches a view from the database the app is running on. Results are
 * passed to the callback, with the first argument of the callback reserved
 * for any exceptions that occurred (node.js style).
 *
 * @param {String} view
 * @param {Object} q (optional)
 * @param {Function} callback
 */

exports.getView = function (view, /*optional*/q, callback) {
    if (!utils.isBrowser) {
        throw new Error('getView cannot be called server-side');
    }
    if (!callback) {
        callback = q;
        q = {};
    }
    var base = utils.getBaseURL();
    var name = exports.encode(settings.name);
    var viewname = exports.encode(view);
    var req = {
        url: base + '/_db/_design/' + name + '/_view/' + viewname,
        data: exports.stringifyQuery(q),
        expect_json: true
    };
    exports.request(req, callback);
};

/**
 * Transforms and fetches a view through a list from the database the app
 * is running on. Results are passed to the callback, with the first
 * argument of the callback reserved for any exceptions that occurred
 * (node.js style).
 *
 * @param {String} list
 * @param {String} view
 * @param {Object} q (optional)
 * @param {Function} callback
 */

// TODO: run list function client-side?
exports.getList = function (list, view, /*optional*/q, callback) {
    if (!utils.isBrowser) {
        throw new Error('getList cannot be called server-side');
    }
    if (!callback) {
        callback = q;
        q = {};
    }
    var base = utils.getBaseURL();
    var name = exports.encode(settings.name);
    var listname = exports.encode(list);
    var viewname = exports.encode(view);
    var req = {
        url: base + '/_db/_design/' + name + '/_list/' + listname +
             '/' + viewname,
        data: exports.stringifyQuery(q)
    };
    exports.request(req, callback);
};

/**
 * Transforms and fetches a document through a show from the database the app
 * is running on. Results are passed to the callback, with the first
 * argument of the callback reserved for any exceptions that occurred
 * (node.js style).
 *
 * @param {String} show
 * @param {String} docid
 * @param {Object} q (optional)
 * @param {Function} callback
 */

// TODO: run show function client-side?
exports.getShow = function (show, docid, /*optional*/q, callback) {
    if (!utils.isBrowser) {
        throw new Error('getShow cannot be called server-side');
    }
    if (!callback) {
        callback = q;
        q = {};
    }
    var base = utils.getBaseURL();
    var name = exports.encode(settings.name);
    var showname = exports.encode(show);
    var show_url = base + '/_db/_design/' + name + '/_show/' + showname;
    var req = {
        url: show_url + (docid ? '/' + exports.encode(docid): ''),
        data: exports.stringifyQuery(q)
    };
    exports.request(req, callback);
};

/**
 * Get all documents (including design docs).
 *
 * @param {Object} q (optional)
 * @param {Function} callback
 * @api public
 */

exports.all = function (/*optional*/q, callback) {
    if (!utils.isBrowser) {
        throw new Error('all cannot be called server-side');
    }
    if (!callback) {
        callback = q;
        q = {};
    }
    var base = utils.getBaseURL();
    var req = {
        url: base + '/_db/_all_docs',
        data: exports.stringifyQuery(q),
        expect_json: true
    };
    exports.request(req, callback);
};

/**
 * Properly encodes query parameters to CouchDB views etc. Handle complex
 * keys and other non-string parameters by passing through JSON.stringify.
 * Returns a shallow-copied clone of the original query after complex values
 * have been stringified.
 *
 * @param {Object} query
 * @returns {Object}
 */

exports.stringifyQuery = function (query) {
    var q = {};
    for (var k in query) {
        if (typeof query[k] !== 'string') {
            q[k] = JSON.stringify(query[k]);
        }
        else {
            q[k] = query[k];
        }
    }
    return q;
};

/**
 * Returns a new UUID generated by CouchDB. Its possible to cache
 * multiple UUIDs for later use, to avoid making too many requests.
 *
 * @param {Number} cacheNum (optional, default: 1)
 * @param {Function} callback
 * @api public
 */

var uuidCache = [];

exports.newUUID = function (cacheNum, callback) {
    if (!utils.isBrowser) {
        throw new Error('newUUID cannot be called server-side');
    }
    if (!callback) {
        callback = cacheNum;
        cacheNum = 1;
    }
    if (uuidCache.length) {
        return callback(null, uuidCache.shift());
    }
    var base = utils.getBaseURL();
    var req = {
        url: '/_uuids',
        data: {count: cacheNum},
        expect_json: true
    };
    exports.request(req, function (err, resp) {
        if (err) {
            return callback(err);
        }
        uuidCache = resp.uuids;
        callback(null, uuidCache.shift());
    });
};
<|endoftext|>


<commit_before>'use strict'
const _ = require('lodash')

function Job(row, queue) {
    _.extend(this, row)
    this.queue = queue
    this.db = queue.db
    this.handled = false
}

Job.prototype.finish = function() {
    this.handled = true
    this.state = 'finished'
    return this.db.none('UPDATE "JobQueue" SET "state"=${state}, "lastRun"=NOW() WHERE "id"=${id}', {
        state: this.state,
        id: this.id
    })
    .then(() => this.queue.logEvent('finished', this))
}

Job.prototype.destroy = function() {
    this.handled = true
    this.state = 'destroyed'
    return this.db.none('DELETE FROM "JobQueue" WHERE "id"=${id}', {
        id: this.id
    })
    .then(() => this.queue.logEvent('destroyed', this))
}

Job.prototype.reschedule = function(date) {
    this.handled = true
    this.state = 'waiting'
    this.scheduledFor = date
    return this.db.none('UPDATE "JobQueue" SET "state"=${state}, "scheduledFor"=${scheduledFor} WHERE "id"=${id}', {
        state: this.state,
        id: this.id,
        scheduledFor: this.scheduledFor
    })
    .then(() => this.queue.logEvent('rescheduled', this))
    .then(() => this.queue.logEvent('finished', this))
}

Job.prototype.fail = function (error, rescheduleFor) {
    let self = this;
    self.handled = true;
    return self.db.tx(function*(t) {
        yield t.none('UPDATE "JobQueue" SET "lastFailureMessage"=${failureMessage}, "failedAttempts"="failedAttempts"+1, "lastRun"=NOW() WHERE "id"=${id}', {
            id: self.id,
            failureMessage: error.message
        });
        let JobQueue = yield t.one('SELECT * FROM "JobQueue" WHERE "id"=${id}', {id: self.id});
        if (JobQueue.failedAttempts >= JobQueue.maxAttempts) {
            // complete failure, ensure the job isn't run again
            self.state = 'failed';
            return yield t.none('UPDATE "JobQueue" SET "state"=${state} WHERE "id"=${id}', {
                id: self.id,
                state: self.state
            });
        }
        // reschedule the job to run in 3 minute
        let now = new Date();
        let minute = 3 * 60 * 1000;
        self.scheduledFor = rescheduleFor || new Date(now.getTime() + minute);
        self.state = 'waiting';
        return yield t.none('UPDATE "JobQueue" SET "state"=${state}, "scheduledFor"=${scheduledFor} WHERE "id"=${id}', {
            id: self.id,
            state: self.state,
            scheduledFor: self.scheduledFor
        });
    })
        .then(() => self.queue.logEvent('failed', self))
        .then(() => self.queue.logError(error, self));
};

module.exports = Job
<commit_msg>fix issue where lastRun would not be updated<commit_after>'use strict'
const _ = require('lodash')

function Job(row, queue) {
    _.extend(this, row)
    this.queue = queue
    this.db = queue.db
    this.handled = false
}

Job.prototype.finish = function() {
    this.handled = true
    this.state = 'finished'
    return this.db.none('UPDATE "JobQueue" SET "state"=${state}, "lastRun"=NOW() WHERE "id"=${id}', {
        state: this.state,
        id: this.id
    })
    .then(() => this.queue.logEvent('finished', this))
}

Job.prototype.destroy = function() {
    this.handled = true
    this.state = 'destroyed'
    return this.db.none('DELETE FROM "JobQueue" WHERE "id"=${id}', {
        id: this.id
    })
    .then(() => this.queue.logEvent('destroyed', this))
}

Job.prototype.reschedule = function(date) {
    this.handled = true
    this.state = 'waiting'
    this.scheduledFor = date
    return this.db.none('UPDATE "JobQueue" SET "state"=${state}, "scheduledFor"=${scheduledFor}, "lastRun"=${lastRun} WHERE "id"=${id}', {
        state: this.state,
        id: this.id,
        scheduledFor: this.scheduledFor,
        lastRun: new Date()
    })
    .then(() => this.queue.logEvent('rescheduled', this))
    .then(() => this.queue.logEvent('finished', this))
}

Job.prototype.fail = function (error, rescheduleFor) {
    let self = this;
    self.handled = true;
    return self.db.tx(function*(t) {
        yield t.none('UPDATE "JobQueue" SET "lastFailureMessage"=${failureMessage}, "failedAttempts"="failedAttempts"+1, "lastRun"=NOW() WHERE "id"=${id}', {
            id: self.id,
            failureMessage: error.message
        });
        let JobQueue = yield t.one('SELECT * FROM "JobQueue" WHERE "id"=${id}', {id: self.id});
        if (JobQueue.failedAttempts >= JobQueue.maxAttempts) {
            // complete failure, ensure the job isn't run again
            self.state = 'failed';
            return yield t.none('UPDATE "JobQueue" SET "state"=${state} WHERE "id"=${id}', {
                id: self.id,
                state: self.state
            });
        }
        // reschedule the job to run in 3 minute
        let now = new Date();
        let minute = 3 * 60 * 1000;
        self.scheduledFor = rescheduleFor || new Date(now.getTime() + minute);
        self.state = 'waiting';
        return yield t.none('UPDATE "JobQueue" SET "state"=${state}, "scheduledFor"=${scheduledFor} WHERE "id"=${id}', {
            id: self.id,
            state: self.state,
            scheduledFor: self.scheduledFor
        });
    })
        .then(() => self.queue.logEvent('failed', self))
        .then(() => self.queue.logError(error, self));
};

module.exports = Job
<|endoftext|>


<commit_before>/**
 * A job takes care of a branch on a repo.
 * Its config is stored in workspace/name_of_job.js
 * The corresponding Git repo used for tests is workspace/name_of_job
 *
 */
var config = require('./config')
  , fs = require('fs')
  , customUtils = require('./customUtils')
  , childProcess = require('child_process')
  , async = require('async')
  ;

/**
 * Constructor. Not to be called directly, use Job.getJob instead.
 */
function Job (options) {
  var name = options.name
    , repo = options.repo
    , branch = options.branch
    ;

  this.name = name;
  this.repo = repo;
  this.branch = branch;
}

/**
 * If job is stored in memory, get it. If not, create it from the given options.
 */
Job.getJob = function (options, callback) {
  if (!options.name) { return callback("This job doesn't have a name"); }

  Job.loadConfig(options.name, function (err, conf) {
    var j;
    if (err) { return callback (err); }

    if (conf) {
      return callback(null, new Job(conf));
    } else {
      j = new Job(options);
      j.save(function (err) {
        return callback(err, j);
      });
    }
  });
};

/**
 * Pull the repo, and create it if it doesn't exist
 */
Job.prototype.pullRepo = function (callback) {
  var self = this;

  if (! this.name) { return callback("This job doesn't seem to have a name ..."); }

  async.waterfall([
    function (cb) {   // Ensure the repo exists, create it if needed
      customUtils.ensureFolderExists(Job.getRepoPath(self.name), function (err) {
        if (err) { return cb(err); }

        fs.readdir(Job.getRepoPath('test'), function (err, files) {
          if (err) { return cb(err); }
          if (files.length > 0) { return cb(); }   // Files were found, we assume it's a Git repo. TODO: check for .git folder

          childProcess.exec('git clone ' + self.repo + ' .', {  cwd: Job.getRepoPath(self.name)  }, function (err, stdout, stderr) {
            return cb(err);
          })
        });
      });
    }
  , function (cb) {   // Pull it (will fail if branch doesn't exist)
      childProcess.exec('set -e; git checkout ' + self.branch + '; git pull', {  cwd: Job.getRepoPath(self.name)  }, function (err, stdout, stderr) {
        return cb(err);
      })
    }
  ], callback);
};

/**
 * (Re)install the dependencies
 */
Job.prototype.reinstallDependencies = function (callback) {
  var self = this;

  if (! this.name) { return callback("This job doesn't seem to have a name ..."); }

  childProcess.exec('set -e; rm -rf node_modules; npm install', { cwd: Job.getRepoPath(self.name) }, function (err, stdout, stderr) {
    callback(err);
  });
};

/**
 * Run the tests
 */
Job.prototype.runTests = function (callback) {
  var self = this;

  if (! this.name) { return callback("This job doesn't seem to have a name ..."); }

  childProcess.exec('make test', { cwd: Job.getRepoPath(self.name) }, function (err, stdout, stderr) {
    console.log(stdout);
    callback(err);
  });

}

/**
 * Save job state in its config file
 */
Job.prototype.save = function (callback) {
  var data, self = this;

  if (! this.name) { return callback("This job doesn't seem to have a name ..."); }

  // Create the js object to be persisted
  function addProperty(obj, prop) {
    if (obj[prop]) {
      data += ", " + prop + ": '" + obj[prop] + "'\n";
    }
  }
  data = "{ name: '" + this.name + "'\n";
  addProperty(this, 'repo');
  addProperty(this, 'branch');
  data += "}";

  customUtils.ensureFolderExists(config.workspace, function (err) {
    if (err) { return callback(err); }
    fs.writeFile(Job.getConfigPath(self.name), data, 'utf8', callback);
  });
};

/**
 * Try to load a job from the filesystem
 */
Job.loadConfig = function (name, callback) {
  fs.exists(Job.getConfigPath(name), function (exists) {
    if (!exists) { return callback(); }

    fs.readFile(Job.getConfigPath(name), 'utf8', function (err, data) {
      var f, config;

      if (err) { return callback(err); }

      try {
        f = new Function('return ' + data);
        config = f();
        return callback(null, config);
      } catch (e) {
        return callback(e);
      }
    });
  });
};

/**
 * Functions defining where the data is stored
 */
Job.getConfigPath = function (name) {
  return config.workspace + '/' + name + '.conf';
};

Job.getRepoPath = function (name) {
  return config.workspace + '/' + name;
};

Job.prototype.hello = function () { console.log("hello"); }

var testJob = { name: 'test'
              , repo: 'git@github.com:tldrio/mongo-edit.git'
              , branch: 'master'
              };

Job.getJob(testJob, function (err, job) {
  //job.pullRepo(function (err) {
    //console.log("REPO PULLED");

    job.runTests(function (err) {
      console.log("TEST RESULT");
      console.log(err);
    });
  //});
});

module.exports = Job;
<commit_msg>Real test script<commit_after>/**
 * A job takes care of a branch on a repo.
 * Its config is stored in workspace/name_of_job.js
 * The corresponding Git repo used for tests is workspace/name_of_job
 *
 */
var config = require('./config')
  , fs = require('fs')
  , customUtils = require('./customUtils')
  , childProcess = require('child_process')
  , async = require('async')
  ;

/**
 * Constructor. Not to be called directly, use Job.getJob instead.
 */
function Job (options) {
  var name = options.name
    , repo = options.repo
    , branch = options.branch
    ;

  this.name = name;
  this.repo = repo;
  this.branch = branch;
}

/**
 * If job is stored in memory, get it. If not, create it from the given options.
 */
Job.getJob = function (options, callback) {
  if (!options.name) { return callback("This job doesn't have a name"); }

  Job.loadConfig(options.name, function (err, conf) {
    var j;
    if (err) { return callback (err); }

    if (conf) {
      return callback(null, new Job(conf));
    } else {
      j = new Job(options);
      j.save(function (err) {
        return callback(err, j);
      });
    }
  });
};

/**
 * Pull the repo, and create it if it doesn't exist
 */
Job.prototype.pullRepo = function (callback) {
  var self = this;

  if (! this.name) { return callback("This job doesn't seem to have a name ..."); }

  async.waterfall([
    function (cb) {   // Ensure the repo exists, create it if needed
      customUtils.ensureFolderExists(Job.getRepoPath(self.name), function (err) {
        if (err) { return cb(err); }

        fs.readdir(Job.getRepoPath('test'), function (err, files) {
          if (err) { return cb(err); }
          if (files.length > 0) { return cb(); }   // Files were found, we assume it's a Git repo. TODO: check for .git folder

          childProcess.exec('git clone ' + self.repo + ' .', {  cwd: Job.getRepoPath(self.name)  }, function (err, stdout, stderr) {
            return cb(err);
          })
        });
      });
    }
  , function (cb) {   // Pull it (will fail if branch doesn't exist)
      childProcess.exec('set -e; git checkout ' + self.branch + '; git pull', {  cwd: Job.getRepoPath(self.name)  }, function (err, stdout, stderr) {
        return cb(err);
      })
    }
  ], callback);
};

/**
 * (Re)install the dependencies
 */
Job.prototype.reinstallDependencies = function (callback) {
  var self = this;

  if (! this.name) { return callback("This job doesn't seem to have a name ..."); }

  childProcess.exec('set -e; rm -rf node_modules; npm install', { cwd: Job.getRepoPath(self.name) }, function (err, stdout, stderr) {
    callback(err);
  });
};

/**
 * Run the tests
 */
Job.prototype.runTests = function (callback) {
  var self = this;

  if (! this.name) { return callback("This job doesn't seem to have a name ..."); }

  childProcess.exec('npm test', { cwd: Job.getRepoPath(self.name) }, function (err, stdout, stderr) {
    console.log(stdout);
    callback(err);
  });

}

/**
 * Save job state in its config file
 */
Job.prototype.save = function (callback) {
  var data, self = this;

  if (! this.name) { return callback("This job doesn't seem to have a name ..."); }

  // Create the js object to be persisted
  function addProperty(obj, prop) {
    if (obj[prop]) {
      data += ", " + prop + ": '" + obj[prop] + "'\n";
    }
  }
  data = "{ name: '" + this.name + "'\n";
  addProperty(this, 'repo');
  addProperty(this, 'branch');
  data += "}";

  customUtils.ensureFolderExists(config.workspace, function (err) {
    if (err) { return callback(err); }
    fs.writeFile(Job.getConfigPath(self.name), data, 'utf8', callback);
  });
};

/**
 * Try to load a job from the filesystem
 */
Job.loadConfig = function (name, callback) {
  fs.exists(Job.getConfigPath(name), function (exists) {
    if (!exists) { return callback(); }

    fs.readFile(Job.getConfigPath(name), 'utf8', function (err, data) {
      var f, config;

      if (err) { return callback(err); }

      try {
        f = new Function('return ' + data);
        config = f();
        return callback(null, config);
      } catch (e) {
        return callback(e);
      }
    });
  });
};

/**
 * Functions defining where the data is stored
 */
Job.getConfigPath = function (name) {
  return config.workspace + '/' + name + '.conf';
};

Job.getRepoPath = function (name) {
  return config.workspace + '/' + name;
};

Job.prototype.hello = function () { console.log("hello"); }

var testJob = { name: 'test'
              , repo: 'git@github.com:tldrio/mongo-edit.git'
              , branch: 'master'
              };

Job.getJob(testJob, function (err, job) {
  //job.pullRepo(function (err) {
    //console.log("REPO PULLED");

    job.runTests(function (err) {
      console.log("TEST RESULT");
      console.log(err);
    });
  //});
});

module.exports = Job;
<|endoftext|>


<commit_before>
/*!
 * mat
 * JavaScript dimension-independent Matrix library
 * Copyright (c) 2012 Enrico Marino (http://onirame.no.de)
 * MIT License
 */

 !(function (exports) {

  /**
   * Library namespace.
   */

  var mat = exports.mat = {};

  /**
   * Library version.
   */

  mat.version = '0.0.2';

  /**
   * Mat
   *
   * @param {Number} n number of rows
   * @param {Number} m number of cols
   * @return {mat.Mat} matrix `n`x`m`
   * @api public
   */

  mat.Mat = function (rows, cols) {
    this.n = n;
    this.m = m;
    this.v = new Float32Array(n*m);
  };

  /**
   * getRow
   * get the i-th row
   *
   * @param {Number} i index of the row to get
   * @return {Float32Array} `i`-th row
   * @api public
   */

  mat.Mat.prototype.getRow = function (i) {
    var cols = this.m;
    var begin = i * cols;
    var end = begin + cols;
    return this.v.subarray(begin, end);
  };

  /**
   * setRow
   * set the i-th row
   *
   * @param {Number} i index of the row to get
   * @param {Float32Array} row row
   * @return {mat.Mat} this for chaining
   * @api public
   */

  mat.Mat.prototype.setRow = function (i, row) {
    var cols = this.m;
    var begin = i * cols;
    this.v.set(row, begin);
    return this;
  };

  /**
   * forEach
   * apply iterator for each row of the matrix
   *
   * @param {Function} iterator iterator
   *   @param {Float32Array} row the i-th row to iterate
   *   @param {Number} i the index of the row to iterate
   * @return {mat.Mat} this for chaining
   * @api public
   */

  mat.Mat.prototype.forEach = function (iterator) {
    var mat = this.v;
    var rows = this.n;
    var cols = this.m;
    var begin = 0;
    var end;
    var row;
    var i;

    for (i = 0; i < rows; i += 1) {
      begin = i * cols;
      end = begin + cols;
      row = new Float32Array(mat.subarray(begin, end));
      iterator(row, i);
    }

    return this;
  };

  /**
   * filter
   * filter the rows that pass the iterator test
   *
   * @param {Function} iterator iterator
   *   @param {Float32Array} row the i-th row to iterate
   *   @param {Number} i the index of the row to iterate
   * @return {mat.Mat} filtered rows
   * @api public
   */

  mat.Mat.prototype.filter = function (iterator) {
    var mat = this.v;
    var rows = this.n;
    var cols = this.m;
    var begin = 0;
    var end;
    var row;
    var i;
    var test;
    var filtered = new Float32Array(rows * cols);
    var k = 0;

    for (i = 0; i < rows; i += 1) {
      begin = i * cols;
      end = begin + cols;
      row = mat.subarray(begin, end);
      test = iterator(row, i);
      if (test) {
        begin = k * cols;
        end = begin + cols;
        filtered.set(begin, end);
        k += 1;
      }
    }

    result = new mat.Mat(k, cols);
    result.v.set(filtered.subarray(0, k * cols));

    return result;
  };

  /**
   * map
   * apply iterator for each row of the matrix
   *
   * @param {Function} iterator iterator
   *   @param {Float32Array} row the i-th row to iterate
   *   @param {Number} i the index of the row to iterate
   * @return {mat.Mat} the mapped matrix
   * @api public
   */

  mat.Mat.prototype.map = function (iterator) {
    var mat = this.v;
    var rows = this.n;
    var cols = this.m;
    var begin = 0;
    var end;
    var row;
    var i;

    for (i = 0; i < rows; i += 1) {
      begin = i * cols;
      end = begin + cols;
      row = mat.subarray(begin, end);
      iterator(row, i);
    }

    return this;
  };

  /**
   * rotate
   *
   * @param {Array} dims
   * @param {Number} angle
   * @return {mat.Mat} this for chaining
   * @api public
   */

  mat.Mat.prototype.rotate = function (dims, angle) {
    var mat = this.v;
    var rows = this.n;
    var cols = this.m;
    var length = rows * cols;
    var cos_a = cos(angle);
    var sin_a = sin(angle);
    var r_ii = cos_a;
    var r_ij = -sin_a;
    var r_ji = sin_a;
    var r_jj = cos_a;
    var d_i = dims[0];
    var d_j = dims[1];
    var i;
    var j;
    var v_i;
    var v_j;
    var k;

    for (k = 0; k < length; k += cols) {
      i = k + d_i;
      j = k + d_j;
      v_i = mat[i];
      v_j = mat[j];
      mat[i] = v_i * r_ii + v_j * r_ij;
      mat[j] = v_i * r_ji + v_j * r_jj;
    }

    return this;
  };

}(this));<commit_msg>added scale<commit_after>
/*!
 * mat
 * JavaScript dimension-independent Matrix library
 * Copyright (c) 2012 Enrico Marino (http://onirame.no.de)
 * MIT License
 */

 !(function (exports) {

  /**
   * Library namespace.
   */

  var mat = exports.mat = {};

  /**
   * Library version.
   */

  mat.version = '0.0.2';

  /**
   * Mat
   *
   * @param {Number} n number of rows
   * @param {Number} m number of cols
   * @return {mat.Mat} matrix `n`x`m`
   * @api public
   */

  mat.Mat = function (rows, cols) {
    this.n = n;
    this.m = m;
    this.v = new Float32Array(n*m);
  };

  /**
   * getRow
   * get the i-th row
   *
   * @param {Number} i index of the row to get
   * @return {Float32Array} `i`-th row
   * @api public
   */

  mat.Mat.prototype.getRow = function (i) {
    var cols = this.m;
    var begin = i * cols;
    var end = begin + cols;
    return this.v.subarray(begin, end);
  };

  /**
   * setRow
   * set the i-th row
   *
   * @param {Number} i index of the row to get
   * @param {Float32Array} row row
   * @return {mat.Mat} this for chaining
   * @api public
   */

  mat.Mat.prototype.setRow = function (i, row) {
    var cols = this.m;
    var begin = i * cols;
    this.v.set(row, begin);
    return this;
  };

  /**
   * forEach
   * apply iterator for each row of the matrix
   *
   * @param {Function} iterator iterator
   *   @param {Float32Array} row the i-th row to iterate
   *   @param {Number} i the index of the row to iterate
   * @return {mat.Mat} this for chaining
   * @api public
   */

  mat.Mat.prototype.forEach = function (iterator) {
    var mat = this.v;
    var rows = this.n;
    var cols = this.m;
    var begin = 0;
    var end;
    var row;
    var i;

    for (i = 0; i < rows; i += 1) {
      begin = i * cols;
      end = begin + cols;
      row = new Float32Array(mat.subarray(begin, end));
      iterator(row, i);
    }

    return this;
  };

  /**
   * filter
   * filter the rows that pass the iterator test
   *
   * @param {Function} iterator iterator
   *   @param {Float32Array} row the i-th row to iterate
   *   @param {Number} i the index of the row to iterate
   * @return {mat.Mat} filtered rows
   * @api public
   */

  mat.Mat.prototype.filter = function (iterator) {
    var mat = this.v;
    var rows = this.n;
    var cols = this.m;
    var begin = 0;
    var end;
    var row;
    var i;
    var test;
    var filtered = new Float32Array(rows * cols);
    var k = 0;

    for (i = 0; i < rows; i += 1) {
      begin = i * cols;
      end = begin + cols;
      row = mat.subarray(begin, end);
      test = iterator(row, i);
      if (test) {
        begin = k * cols;
        end = begin + cols;
        filtered.set(begin, end);
        k += 1;
      }
    }

    result = new mat.Mat(k, cols);
    result.v.set(filtered.subarray(0, k * cols));

    return result;
  };

  /**
   * map
   * apply iterator for each row of the matrix
   *
   * @param {Function} iterator iterator
   *   @param {Float32Array} row the i-th row to iterate
   *   @param {Number} i the index of the row to iterate
   * @return {mat.Mat} the mapped matrix
   * @api public
   */

  mat.Mat.prototype.map = function (iterator) {
    var mat = this.v;
    var rows = this.n;
    var cols = this.m;
    var begin = 0;
    var end;
    var row;
    var i;

    for (i = 0; i < rows; i += 1) {
      begin = i * cols;
      end = begin + cols;
      row = mat.subarray(begin, end);
      iterator(row, i);
    }

    return this;
  };

  /**
   * rotate
   *
   * @param {Array} dims
   * @param {Number} angle
   * @return {mat.Mat} this for chaining
   * @api public
   */

  mat.Mat.prototype.rotate = function (dims, angle) {
    var mat = this.v;
    var rows = this.n;
    var cols = this.m;
    var length = rows * cols;
    var cos_a = cos(angle);
    var sin_a = sin(angle);
    var r_ii = cos_a;
    var r_ij = -sin_a;
    var r_ji = sin_a;
    var r_jj = cos_a;
    var d_i = dims[0];
    var d_j = dims[1];
    var i;
    var j;
    var v_i;
    var v_j;
    var k;

    for (k = 0; k < length; k += cols) {
      i = k + d_i;
      j = k + d_j;
      v_i = mat[i];
      v_j = mat[j];
      mat[i] = v_i * r_ii + v_j * r_ij;
      mat[j] = v_i * r_ji + v_j * r_jj;
    }

    return this;
  };

  /**
   * scale
   *
   * @param {Array|Uint32Array} dims
   * @param {Array|Float32Array} values
   * @return {simplexn.PointSet} this for chaining
   * @api public
   */

  mat.Mat.prototype.scale = function (dims, values) {
    var mat = this.v;
    var rows = this.rows;
    var cols = this.cols;
    var length = dims.length;
    var i;
    var j;

    for (i = 0; i < rows; i++) {
      for (j = 0; j < length; j++) {
        mat[i * cols + dims[j]] *= values[j];
      }
    }

    return this;
  };

}(this));<|endoftext|>


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

var utils = require('./utils');
var datastores = require('./datastores');
var ModelConstructor = require('./model').ModelConstructor;

function Orm(options) {
  // Check for required options.
  utils.requireAttributes(options, ['redisClient', 'cassandraClient'])

  // Revert to a very simple id generator when `generateId` is not defined.
  this.generateId = options.generateId
  if (!this.generateId) {
    var i = 0;
    this.generateId = function() {
      i++;
      return i;
    }
  }

  // Initialize the orm's datastores from the options.
  this.datastores = {
    redis: new datastores.RedisDatastore({
      client: options.redisClient,
      keyspace: options.redisKeyspace
    }),
    cassandra: new datastores.CassandraDatastore({
      client: options.cassandraClient
    })
  }

  // Get base transforms.
  this.modelTransforms = options.modelTransforms || [];

  // Initialize a container for the orm's registered models.
  this.models = {};
}

/**
 * Creates a model, registers it with the orm, and returns it.
 * @param  {string} name - the model's name
 * @param  {object} options - the model's options
 * @return {Model} - the created model
 */
Orm.prototype.createModel = function(name, options) {
  // Check that the model's name is not already registered.
  if (name in this.models) {
    throw new Error('model `' + name + '` is already defined');
  }

  var model = new ModelConstructor(name, this, options);
  this.models[name] = model;

  return model;
}

/**
 * Creates an orm instance and returns it.
 * @param  {objects} options - the orm's options
 * @return {Orm} - the created orm
 */
function createOrm(options) {
  var orm = new Orm(options);
  return orm;
}

module.exports = createOrm;
<commit_msg>Use the lodash id generator<commit_after>var _ = require('lodash');

var utils = require('./utils');
var datastores = require('./datastores');
var ModelConstructor = require('./model').ModelConstructor;

function Orm(options) {
  // Check for required options.
  utils.requireAttributes(options, ['redisClient', 'cassandraClient'])

  // Revert to a very simple id generator when `generateId` is not defined.
  this.generateId = options.generateId || _.uniqueId();

  // Initialize the orm's datastores from the options.
  this.datastores = {
    redis: new datastores.RedisDatastore({
      client: options.redisClient,
      keyspace: options.redisKeyspace
    }),
    cassandra: new datastores.CassandraDatastore({
      client: options.cassandraClient
    })
  }

  // Get base transforms.
  this.modelTransforms = options.modelTransforms || [];

  // Initialize a container for the orm's registered models.
  this.models = {};
}

/**
 * Creates a model, registers it with the orm, and returns it.
 * @param  {string} name - the model's name
 * @param  {object} options - the model's options
 * @return {Model} - the created model
 */
Orm.prototype.createModel = function(name, options) {
  // Check that the model's name is not already registered.
  if (name in this.models) {
    throw new Error('model `' + name + '` is already defined');
  }

  var model = new ModelConstructor(name, this, options);
  this.models[name] = model;

  return model;
}

/**
 * Creates an orm instance and returns it.
 * @param  {objects} options - the orm's options
 * @return {Orm} - the created orm
 */
function createOrm(options) {
  var orm = new Orm(options);
  return orm;
}

module.exports = createOrm;
<|endoftext|>


<commit_before>var path = require('path'),
    fs = require('fs'),
    config = require('./config')(),
    profile = require('./profile'),
    mkdirp = require('./fsutil').mkdirp,
    rm = require('./fsutil').rm,
    semver = require('semver');

var Package = function(q, version) {
    'use strict';

    var baseDir = q.isWorkingPackage ? config.cwd : q.provider.getDirectory(q.name, version);

    Object.defineProperties(this, {
        url: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: q.provider.normalizeUrl(q.name + '#' + version)
        },
        baseDir: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: baseDir,
        },
        name: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: q.name,
        },
        version: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: version,
        },
        isWorkingPackage: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: q.isWorkingPackage,
        },
        query: {
            enumerable: false,
            writable: true,
            configurable: false,
            value: q
        },
        dependencies: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: {},
        },
        modules: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: [],
        },
        deploy: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: {}
        },
        profile: {
            enumerable: false,
            writable: true,
            configurable: false
        },
    });
};

Package.prototype.populateData = function() {
    'use strict';

    if (fs.existsSync(this.baseDir)) {
        return this.getProfile().readManifest(this.baseDir)
            .then(function(manifest) {
                for(var i in manifest) {
                    if (i === 'profile' || i === 'version') {
                        continue;
                    }
                    if (i === 'name' && !this.isWorkingPackage) {
                        continue;
                    }
                    this[i] = manifest[i];
                }
            }.bind(this));
    } else {
        return Promise.resolve();
    }
};

Package.prototype.getProfile = function() {
    'use strict';

    if (!this.profile) {
        this.profile = profile.detect(this.baseDir);
    }

    return this.profile;
};

Package.prototype.initialize = function() {
    'use strict';

    return this.populateData()
        .then(function() {
            return this;
        }.bind(this));
};

Package.prototype.pull = function() {
    'use strict';

    var to = this.query.provider.getDirectory(this.name, this.version),
        type = semver.valid(this.version) ? 'releases' : 'devs';

    var from = this.query.indices[type][this.version];

    if (type === 'releases' && fs.existsSync(to)) {
        return;
    }

    return this.query.provider.pull(from, to)
        .then(function() {
            return this.populateData();
        }.bind(this));
};

Package.prototype.readManifest = function() {
    'use strict';

    var manifestFile = path.join(config.cwd, 'pas.json');
    var manifest = require(manifestFile);
    return manifest;
};

Package.prototype.writeManifest = function(manifest) {
    'use strict';

    var manifestFile = path.join(config.cwd, 'pas.json');
    fs.writeFileSync(manifestFile, JSON.stringify(manifest, null, 2));
    delete require.cache[manifestFile];
};

Package.prototype.getCacheDirectory = function() {
    'use strict';

    return this.query.provider.getDirectory(this.name, this.version);
};

Package.prototype.createLink = function() {
    'use strict';

    var destinationDir = this.getCacheDirectory();

    if (!fs.existsSync(destinationDir)) {
        mkdirp(path.join(destinationDir, '..'));
        return Promise.denodeify(fs.symlink)(config.cwd, destinationDir);
    }
};

Package.prototype.deleteLink = function() {
    'use strict';

    var destinationDir = this.getCacheDirectory();

    return new Promise(function(resolve, reject) {

        if (fs.existsSync(destinationDir)) {
            fs.unlink(destinationDir, function(err) {
                if (err) return reject(err);
                resolve();
            });
        } else {
            resolve();
        }
    });
};

Package.prototype.getInstalledVersion = function() {
    'use strict';

    var vendorDir = this.getInstalledDirectory();
    if (fs.existsSync(vendorDir)) {
        var realPath = fs.realpathSync(vendorDir);
        return path.basename(realPath);
    } else {
        return '';
    }
};

Package.prototype.getInstalledDirectory = function() {
    'use strict';

    return path.join(config.cwd, this.getProfile().vendorDirectory, this.name);
};

Package.prototype.preInstall = function() {
    'use strict';

    if (this.getProfile().preInstall) {
        return Promise.resolve(this.getProfile().preInstall(this));
    }

    return Promise.resolve();
};

Package.prototype.postInstall = function() {
    'use strict';

    if (this.getProfile().postInstall) {
        return Promise.resolve(this.getProfile().postInstall(this));
    }
};

Package.prototype.link = function(otherPackage) {
    'use strict';

    return new Promise(function(resolve, reject) {
        var origin = otherPackage.getCacheDirectory(),
            destination = otherPackage.getInstalledDirectory();

        if (fs.existsSync(destination)) {
            rm(destination);
        }

        if (fs.existsSync(origin)) {
            mkdirp(path.join(destination, '..'));
            fs.symlink(origin, destination, function(err) {
                if (err) {
                    return reject(err);
                }
                resolve(null, otherPackage);
            });
        }
    }.bind(this));
};

Package.prototype.unlink = function(otherPackage) {
    'use strict';

    var packagePath = otherPackage.getInstalledDirectory();
    if (fs.existsSync(packagePath)) {
        return rm(packagePath);
    }
};

module.exports = Package;
<commit_msg>ADDED package.manifest()<commit_after>var path = require('path'),
    fs = require('fs'),
    config = require('./config')(),
    profile = require('./profile'),
    mkdirp = require('./fsutil').mkdirp,
    rm = require('./fsutil').rm,
    semver = require('semver');

var manifestCache = {};

var Package = module.exports = function(q, version) {
    'use strict';

    var baseDir = q.isWorkingPackage ? config.cwd : q.provider.getDirectory(q.name, version);

    Object.defineProperties(this, {
        url: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: q.provider.normalizeUrl(q.name + '#' + version)
        },
        baseDir: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: baseDir,
        },
        name: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: q.name,
        },
        version: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: version,
        },
        isWorkingPackage: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: q.isWorkingPackage,
        },
        query: {
            enumerable: false,
            writable: true,
            configurable: false,
            value: q
        },
        dependencies: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: {},
        },
        modules: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: [],
        },
        deploy: {
            enumerable: true,
            writable: true,
            configurable: false,
            value: {}
        },
        profile: {
            enumerable: false,
            writable: true,
            configurable: false
        },
    });
};

Package.prototype.populateData = function() {
    'use strict';

    if (fs.existsSync(this.baseDir)) {
        return this.getProfile().readManifest(this.baseDir)
            .then(function(manifest) {
                for(var i in manifest) {
                    if (i === 'profile' || i === 'version') {
                        continue;
                    }
                    if (i === 'name' && !this.isWorkingPackage) {
                        continue;
                    }
                    this[i] = manifest[i];
                }
            }.bind(this));
    } else {
        return Promise.resolve();
    }
};

Package.prototype.getProfile = function() {
    'use strict';

    if (!this.profile) {
        this.profile = profile.detect(this.baseDir);
    }

    return this.profile;
};

Package.prototype.initialize = function() {
    'use strict';

    return this.populateData()
        .then(function() {
            return this;
        }.bind(this));
};

Package.prototype.pull = function() {
    'use strict';

    var to = this.query.provider.getDirectory(this.name, this.version),
        type = semver.valid(this.version) ? 'releases' : 'devs';

    var from = this.query.indices[type][this.version];

    if (type === 'releases' && fs.existsSync(to)) {
        return;
    }

    return this.query.provider.pull(from, to)
        .then(function() {
            return this.populateData();
        }.bind(this));
};

Package.prototype.readManifest = function() {
    'use strict';

    var manifestFile = path.join(config.cwd, 'pas.json');
    var manifest = require(manifestFile);
    return manifest;
};

Package.prototype.writeManifest = function(manifest) {
    'use strict';

    var manifestFile = path.join(config.cwd, 'pas.json');
    fs.writeFileSync(manifestFile, JSON.stringify(manifest, null, 2));
    delete require.cache[manifestFile];
};

Package.prototype.getCacheDirectory = function() {
    'use strict';

    return this.query.provider.getDirectory(this.name, this.version);
};

Package.prototype.createLink = function() {
    'use strict';

    var destinationDir = this.getCacheDirectory();

    if (!fs.existsSync(destinationDir)) {
        mkdirp(path.join(destinationDir, '..'));
        return Promise.denodeify(fs.symlink)(config.cwd, destinationDir);
    }
};

Package.prototype.deleteLink = function() {
    'use strict';

    var destinationDir = this.getCacheDirectory();

    return new Promise(function(resolve, reject) {

        if (fs.existsSync(destinationDir)) {
            fs.unlink(destinationDir, function(err) {
                if (err) return reject(err);
                resolve();
            });
        } else {
            resolve();
        }
    });
};

Package.prototype.getInstalledVersion = function() {
    'use strict';

    var vendorDir = this.getInstalledDirectory();
    if (fs.existsSync(vendorDir)) {
        var realPath = fs.realpathSync(vendorDir);
        return path.basename(realPath);
    } else {
        return '';
    }
};

Package.prototype.getInstalledDirectory = function() {
    'use strict';

    return path.join(config.cwd, this.getProfile().vendorDirectory, this.name);
};

Package.prototype.preInstall = function() {
    'use strict';

    if (this.getProfile().preInstall) {
        return Promise.resolve(this.getProfile().preInstall(this));
    }

    return Promise.resolve();
};

Package.prototype.postInstall = function() {
    'use strict';

    if (this.getProfile().postInstall) {
        return Promise.resolve(this.getProfile().postInstall(this));
    }
};

Package.prototype.link = function(otherPackage) {
    'use strict';

    return new Promise(function(resolve, reject) {
        var origin = otherPackage.getCacheDirectory(),
            destination = otherPackage.getInstalledDirectory();

        if (fs.existsSync(destination)) {
            rm(destination);
        }

        if (fs.existsSync(origin)) {
            mkdirp(path.join(destination, '..'));
            fs.symlink(origin, destination, function(err) {
                if (err) {
                    return reject(err);
                }
                resolve(null, otherPackage);
            });
        }
    }.bind(this));
};

Package.prototype.unlink = function(otherPackage) {
    'use strict';

    var packagePath = otherPackage.getInstalledDirectory();
    if (fs.existsSync(packagePath)) {
        return rm(packagePath);
    }
};

Package.manifest = function(cwd, nocache) {
    'use strict';

    cwd = cwd || config.cwd;

    if (!nocache && manifestCache[cwd]) {
        return manifestCache[cwd];
    }

    var copy = function(from) {
        var result = {};
        for(var key in from) {
            if (typeof from[key] === 'object' && !Array.isArray(from[key])) {
                result[key] = copy(from[key]);
            } else {
                result[key] = from[key];
            }
        }

        return result;
    };

    var merge = function(to, from) {
        for(var i in from) {
            var f = i.split('!'),
                key = f[0],
                action = f.length === 1 ? 'merge' : f[1];

            if (action === 'unset') {
                delete to[key];
            } else if (action === 'set') {
                to[key] = copy(from[i]);
            } else if (typeof from[key] === 'object' && !Array.isArray(from[key])) {
                if (typeof to[key] !== 'object' || Array.isArray(from[key])) {
                    to[key] = {};
                }
                merge(to[key], from[key]);
            } else {
                to[key] = from[key];
            }
        }
    };

    var manifestFile = path.join(cwd, 'pas.json');
    var manifest = copy(require(manifestFile));

    try {
        var envManifest = require(path.join(cwd, 'pas-' + config.env + '.json'));
        merge(manifest, envManifest);
    } catch(e) {
        console.log(e.message);
    }

    manifestCache[cwd] = manifest;

    return manifest;
};
<|endoftext|>