<commit_before>#!/usr/bin/env node

var util = require('./util')
var colors = require('colors')
var commander = require('commander')
var parser = require('./query_parser')
var pjson = require('./package.json')
var async = require('async')
var readline = require('readline')

var config = util.load_config()
if (!config) {
  return
}

commander
  .version(pjson.version)
  // Actions
  .option('-l, --list_accounts', 'List accounts')
  .option('-k, --keys <key>', 'List searchable keys for a cloud provider')
  // Filters
  .option('-r, --region <region>', 'Aws region', util.list)
  .option('-a, --account <account>', 'Account name', util.list)
  .option('-t, --type <type>', 'Type of account', util.list)
  // Query shortcuts
  .option('-n, --servername <name>', 'Filter by name', util.list)
  .option('-H, --hostname <hostname>', 'Filter by hostname', util.list)
  .option('-i, --ip <ip>', 'Filter by ip', util.list)
  .option('-I, --image <image>', 'Filter by image id', util.list)
  .option('--id <id>', 'Filter by instance id', util.list)
  //Misc
  .option('-q, --query <query>', 'Query')
  .option('-e, --enable_filters <filter>', 'Enable specific filter(s)', util.list)
  // SSH options
  .option('-u, --user <user>', 'SSH user')
  .option('-p, --port <port>', 'SSH port')
  .option('-K, --keyfile <keyfile>', 'SSH keyfile')
  .option('-c, --ssh_command <ssh_command>', 'Command to execute')
  .option('-P, --private_ip', 'Use private ip when connecting')
  // Boolean options
  .option('-A, --run_on_all', 'Execute on all found hosts')
  .option('-f, --force_regions', 'Use specified region for all accounts regardless of configured regions')
  .parse(process.argv)

var force_regions = commander.force_regions || config.force_regions

var alias

if (commander.args.length > 0) {
  if (config.alias[commander.args.join(' ')]) {
    alias = config.alias[commander.args.join(' ')]
  }
}

var parse_arguments = function () {
  var regions = []
  var accounts = []

  if (commander.region) {
    regions = commander.region
  }

  if (commander.account || (alias && alias.accounts)) {
    accounts = config.credentials.filter(function (account) {
      return util.contains_with_lowercase(account.name.toLowerCase(), commander.account ? commander.account : alias.accounts) || (account.public_token && util.contains_with_lowercase(account.public_token.toLowerCase(), commander.account ? commander.account : alias.accounts))
    })

    accounts = accounts.filter(util.check_account_type)

    if (!accounts.length) {
      return console.log('No accounts found with this name or public token'.red)
    }
  } else {
    if (!config.credentials || !config.credentials.length) {
      return console.log('No accounts defined in config'.red)
    }

    accounts = config.credentials.filter(util.check_account_type)
  }

  if (commander.type) {
    var valid_types = []

    commander.type.forEach(function (type) {
      if (config.plugins.indexOf(type.toLowerCase()) === -1) {
        console.log('Ignoring invalid type %s, valid types: [%s]'.red, type, config.plugins)
      } else {
        valid_types.push(type.toLowerCase())
      }
    })

    accounts = accounts.filter(function (account) {
      return util.contains(account.type.toLowerCase(), valid_types)
    })
  }

  if (!accounts.length) {
    return console.log('No valid accounts found'.red)
  }

  setup_filters(accounts, regions)
}

var setup_filters = function (accounts, regions) {
  var filters = ''
  var filter_list = []

  if (commander.enable_filters || (config.enabled_filters && config.enabled_filters.length)) {
    if (commander.enable_filters) {
      filter_list = filter_list.concat(commander.enable_filters.filter(function (filter) {
        if (config.allowed_filters.indexOf(filter.toLowerCase()) > -1) {
          return true
        } else {
          console.log('Ignoring invalid/disallowed filter %s'.red, filter)
          return false
        }
      }))
    }

    if (config.enabled_filters && config.enabled_filters.length) {
      filter_list = filter_list.concat(config.enabled_filters)
    }

    filter_list = util.deduplicate_array(filter_list)

    async.each(filter_list, function (filter, next) {
      try {
        require('./plugins/' + filter.toLowerCase()).filter(config, function (filter) {
          filters += filter
          next()
        })
      } catch (error) {
        next(error)
      }
    }, function (error) {
      if (error) {
        console.log('Something went wrong while setting up filters: %s'.red, error)
      }

      gather_servers(accounts, regions, filters.trim())
    })
  } else {
    gather_servers(accounts, regions, filters)
  }
}

var gather_servers = function (accounts, regions, filters) {
  var accounts_to_use = []

  if (!regions || !regions.length) {
    regions = []
    accounts.forEach(function (account) {
      if (!account.regions) {
        account.regions = require('./plugins/' + account.type).regions
      }

      account.regions.forEach(function (region) {
        if (regions.indexOf(region) === -1) {
          regions.push(region)
        }
      })
    })
  }

  accounts.forEach(function (account) {
    if ((force_regions && commander.region) || (alias && alias.regions)) {
      account.regions = commander.region ? commander.region : alias.regions
      account.regions = account.regions.filter(function (region) {
        return require('./plugins/' + account.type).regions.indexOf(region) > -1
      })
    } else {
      if (!account.regions) {
        account.regions = require('./plugins/' + account.type).regions
      }

      account.regions = account.regions.filter(function (region) {
        return regions.indexOf(region) > -1
      })
    }

    if (account.regions.length) {
      accounts_to_use.push(account)
      console.log('Using %s account %s (%s)' + (account.public_token ? ' - %s' : '').green, colors.blue(account.type), colors.green(account.name), colors.yellow(account.regions), account.public_token ? colors.red(account.public_token) : '')
    }
  })

  if (!accounts_to_use.length) {
    return console.log('No accounts with correct regions found'.red)
  }

  async.concat(accounts_to_use, function (account, next) {
    util.find_servers(account, function callback (servers) {
      next(null, servers)
    })
  }, function (error, servers) {
    if (!servers.length) {
      return console.log('No matching servers found'.red)
    }

    filter_results(filters, servers)
  })
}

var filter_results = function (filters, servers) {
  if (commander.query || commander.region || commander.servername || commander.hostname || commander.image || commander.ip || commander.id || alias || (filters && filters.length)) {
    try {
      var query = parser.generate_query_ast_sync(build_query(filters))
    } catch (error) {
      console.log('Invalid query: %s'.red, error.message)
      return
    }

    async.concat(servers, function (server, next) {
      parser.match(JSON.parse(JSON.stringify(server)), query, function (error, matches) {
        next(error, matches ? server : [])
      })
    }, function (error, servers) {
      if (!servers.length) {
        return console.log('No matching servers found'.red)
      }

      display_results(servers)
    })
  } else {
    display_results(servers)
  }
}

var build_query = function (filters) {
  var query = ''

  if (commander.servername) {
    query += build_query_part('name', commander.servername)
  }

  if (commander.region) {
    query += build_query_part('region', commander.region)
  }

  if (commander.hostname) {
    query += build_query_part('hostname', commander.hostname)
  }

  if (commander.image) {
    query += build_query_part('image', commander.image)
  }

  if (commander.ip) {
    query += build_query_part('ip', commander.ip)
  }

  if (commander.id) {
    query += build_query_part('id', commander.id)
  }

  if (filters) {
    query += ' AND (' + filters + ')'
  }

  if (commander.query) {
    if (!query.length) {
      query += commander.query
    } else {
      query += ' AND (' + commander.query + ')'
    }
  }

  if (alias && alias.query) {
    query += ' AND (' + alias.query + ')'
  }

  query = query.trim()

  if (util.starts_with(query, 'AND')) {
    query = query.substring(3)
  }

  if (util.starts_with(query, 'OR')) {
    query = query.substring(2)
  }

  return query.trim()
}

var build_query_part = function (key_name, key) {
  var query = ' AND ('
  var split_count = key.length

  key.forEach(function (split) {
    split_count--

    query += key_name + ' CONTAINS' + ' \'' + split + '\''

    if (split_count) {
      query += ' OR '
    }
  })

  query += ')'

  return query
}

var display_results = function (result) {
  var color_index = 0
  var index = 0

  result.forEach(function (server) {
    require('./plugins/' + server.account.type).display(server, index+++1)
  })

  if (result.length == 1 && config.auto_connect_on_one_result) {
    return prepare_ssh(result[0])
  }

  if (((alias && alias.run_on_all) || commander.run_on_all) && ((alias && alias.command) || commander.ssh_command)) {
    return result.forEach(function (server) {
      prepare_ssh(server, util.colors[color_index++])

      if (color_index > (util.colors.length - 1)) {
        color_index = 0
      }
    })
  }

  var reader = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  })

  reader.question("Which server do you want to connect to? ", function (index) {
    var server = result[index - 1]
    reader.close()

    if (!server) {
      return console.log('Invalid selection'.red)
    }

    prepare_ssh(server)
  })
}

var prepare_ssh = function (server, disable_tt) {
  var ssh_config

  if (!config.ssh_config.length) {
    return console.log('Please specify a default ssh config'.red)
  }

  function iterate_configs (the_config, next) {
    var account_match = false
    var query

    if (the_config.priority === 0) {
      ssh_config = the_config
      return next()
    }

    if (the_config.accounts && (util.contains_with_lowercase(server.account.name.toLowerCase(), the_config.accounts) || (server.account.public_token && util.contains_with_lowercase(server.account.public_token.toLowerCase(), the_config.accounts)))) {
      account_match = true
    }

    if (!the_config.query) {
      if (account_match) {
        if (!ssh_config || the_config.priority > ssh_config.priority) {
          ssh_config = the_config
        }
      }

      return next()
    }

    try {
      query = parser.generate_query_ast_sync(the_config.query)
    } catch (error) {
      return console.log('Invalid ssh config query: %s'.red, error.message)
    }

    parser.match(JSON.parse(JSON.stringify(server)), query, function (error, matches) {
      if (error) {
        return console.log('Error parsing with ssh config query %s'.red, error)
      }

      if (matches) {
        if ((the_config.accounts && account_match) || !the_config.accounts) {
          if (!ssh_config || the_config.priority > ssh_config.priority) {
            ssh_config = the_config
          }
        }
      }

      next(error)
    })
  }

  function next (error) {
    ssh(server, ssh_config, disable_tt)
  }

  async.each(config.ssh_config, iterate_configs, next)
}

var ssh = function (server, ssh_config, disable_tt) {
  // TODO Merge default conf with ssh config, config option?
  if (ssh_config) {
    if (alias && alias.user) {
      ssh_config.user = alias.user
    }

    if (commander.user) {
      ssh_config.user = commander.user
    }

    if (alias && alias.port) {
      ssh_config.port = alias.port
    }

    if (commander.port) {
      ssh_config.port = commander.port
    }

    if (alias && alias.keyfile) {
      ssh_config.keyfile = alias.keyfile
    }

    if (commander.keyfile) {
      ssh_config.keyfile = commander.keyfile
    }

    if (alias && alias.command) {
      ssh_config.command = alias.command
    }

    if (commander.ssh_command) {
      ssh_config.command = commander.ssh_command
    }

    if (alias && alias.private_ip) {
      ssh_config.private_ip = true
    }

    if (commander.private_ip) {
      ssh_config.private_ip = true
    }

    ssh_config.port = ssh_config.port ? ssh_config.port : 22
    ssh_config.user = ssh_config.user ? ssh_config.user : 'root'

    var options = {
      user: ssh_config.user,
      port: ssh_config.port,
      keyfile: ssh_config.keyfile,
      command: ssh_config.command,
      disable_tt: disable_tt,
      private_ip: ssh_config.private_ip,
      extra_options: []
    }

    if (ssh_config.options && ssh_config.options.length) {
      options.extra_options = ssh_config.options
    }

    if (alias && alias.options) {
      options.extra_options = alias.options
    }

    require('./plugins/' + server.account.type).ssh(server, options)

    return
  }

  console.log('No matching ssh config, please specify a default ssh config'.red)
}

// Commands

if (commander.list_accounts) {
  config.credentials.forEach(function (account) {
    console.log('%s %s (%s)' + (account.public_token ? ' - %s' : ''), account.name.green, account.type.blue, colors.yellow(account.regions ? account.regions : require('./plugins/' + account.type).regions), account.public_token ? colors.red(account.public_token) : '')
  })
  return
}

if (commander.keys) {
  try {
    console.log("Keys for %s: %s".white, colors.blue(commander.keys), require('./plugins/' + commander.keys).keys.join(", "))
  } catch (error) {
    console.error('Provided type \'%s\' does not exist'.red, commander.keys)
  }
  return
}

parse_arguments()<commit_msg>Refactor building of the ssh config<commit_after>#!/usr/bin/env node

var util = require('./util')
var colors = require('colors')
var commander = require('commander')
var parser = require('./query_parser')
var pjson = require('./package.json')
var async = require('async')
var readline = require('readline')

var config = util.load_config()
if (!config) {
  return
}

commander
  .version(pjson.version)
  // Actions
  .option('-l, --list_accounts', 'List accounts')
  .option('-k, --keys <key>', 'List searchable keys for a cloud provider')
  // Filters
  .option('-r, --region <region>', 'Aws region', util.list)
  .option('-a, --account <account>', 'Account name', util.list)
  .option('-t, --type <type>', 'Type of account', util.list)
  // Query shortcuts
  .option('-n, --servername <name>', 'Filter by name', util.list)
  .option('-H, --hostname <hostname>', 'Filter by hostname', util.list)
  .option('-i, --ip <ip>', 'Filter by ip', util.list)
  .option('-I, --image <image>', 'Filter by image id', util.list)
  .option('--id <id>', 'Filter by instance id', util.list)
  //Misc
  .option('-q, --query <query>', 'Query')
  .option('-e, --enable_filters <filter>', 'Enable specific filter(s)', util.list)
  // SSH options
  .option('-u, --user <user>', 'SSH user')
  .option('-p, --port <port>', 'SSH port')
  .option('-K, --keyfile <keyfile>', 'SSH keyfile')
  .option('-c, --ssh_command <ssh_command>', 'Command to execute')
  .option('-P, --private_ip', 'Use private ip when connecting')
  // Boolean options
  .option('-A, --run_on_all', 'Execute on all found hosts')
  .option('-f, --force_regions', 'Use specified region for all accounts regardless of configured regions')
  .parse(process.argv)

var force_regions = commander.force_regions || config.force_regions

var alias

if (commander.args.length > 0) {
  if (config.alias[commander.args.join(' ')]) {
    alias = config.alias[commander.args.join(' ')]
  }
}

var parse_arguments = function () {
  var regions = []
  var accounts = []

  if (commander.region) {
    regions = commander.region
  }

  if (commander.account || (alias && alias.accounts)) {
    accounts = config.credentials.filter(function (account) {
      return util.contains_with_lowercase(account.name.toLowerCase(), commander.account ? commander.account : alias.accounts) || (account.public_token && util.contains_with_lowercase(account.public_token.toLowerCase(), commander.account ? commander.account : alias.accounts))
    })

    accounts = accounts.filter(util.check_account_type)

    if (!accounts.length) {
      return console.log('No accounts found with this name or public token'.red)
    }
  } else {
    if (!config.credentials || !config.credentials.length) {
      return console.log('No accounts defined in config'.red)
    }

    accounts = config.credentials.filter(util.check_account_type)
  }

  if (commander.type) {
    var valid_types = []

    commander.type.forEach(function (type) {
      if (config.plugins.indexOf(type.toLowerCase()) === -1) {
        console.log('Ignoring invalid type %s, valid types: [%s]'.red, type, config.plugins)
      } else {
        valid_types.push(type.toLowerCase())
      }
    })

    accounts = accounts.filter(function (account) {
      return util.contains(account.type.toLowerCase(), valid_types)
    })
  }

  if (!accounts.length) {
    return console.log('No valid accounts found'.red)
  }

  setup_filters(accounts, regions)
}

var setup_filters = function (accounts, regions) {
  var filters = ''
  var filter_list = []

  if (commander.enable_filters || (config.enabled_filters && config.enabled_filters.length)) {
    if (commander.enable_filters) {
      filter_list = filter_list.concat(commander.enable_filters.filter(function (filter) {
        if (config.allowed_filters.indexOf(filter.toLowerCase()) > -1) {
          return true
        } else {
          console.log('Ignoring invalid/disallowed filter %s'.red, filter)
          return false
        }
      }))
    }

    if (config.enabled_filters && config.enabled_filters.length) {
      filter_list = filter_list.concat(config.enabled_filters)
    }

    filter_list = util.deduplicate_array(filter_list)

    async.each(filter_list, function (filter, next) {
      try {
        require('./plugins/' + filter.toLowerCase()).filter(config, function (filter) {
          filters += filter
          next()
        })
      } catch (error) {
        next(error)
      }
    }, function (error) {
      if (error) {
        console.log('Something went wrong while setting up filters: %s'.red, error)
      }

      gather_servers(accounts, regions, filters.trim())
    })
  } else {
    gather_servers(accounts, regions, filters)
  }
}

var gather_servers = function (accounts, regions, filters) {
  var accounts_to_use = []

  if (!regions || !regions.length) {
    regions = []
    accounts.forEach(function (account) {
      if (!account.regions) {
        account.regions = require('./plugins/' + account.type).regions
      }

      account.regions.forEach(function (region) {
        if (regions.indexOf(region) === -1) {
          regions.push(region)
        }
      })
    })
  }

  accounts.forEach(function (account) {
    if ((force_regions && commander.region) || (alias && alias.regions)) {
      account.regions = commander.region ? commander.region : alias.regions
      account.regions = account.regions.filter(function (region) {
        return require('./plugins/' + account.type).regions.indexOf(region) > -1
      })
    } else {
      if (!account.regions) {
        account.regions = require('./plugins/' + account.type).regions
      }

      account.regions = account.regions.filter(function (region) {
        return regions.indexOf(region) > -1
      })
    }

    if (account.regions.length) {
      accounts_to_use.push(account)
      console.log('Using %s account %s (%s)' + (account.public_token ? ' - %s' : '').green, colors.blue(account.type), colors.green(account.name), colors.yellow(account.regions), account.public_token ? colors.red(account.public_token) : '')
    }
  })

  if (!accounts_to_use.length) {
    return console.log('No accounts with correct regions found'.red)
  }

  async.concat(accounts_to_use, function (account, next) {
    util.find_servers(account, function callback (servers) {
      next(null, servers)
    })
  }, function (error, servers) {
    if (!servers.length) {
      return console.log('No matching servers found'.red)
    }

    filter_results(filters, servers)
  })
}

var filter_results = function (filters, servers) {
  if (commander.query || commander.region || commander.servername || commander.hostname || commander.image || commander.ip || commander.id || alias || (filters && filters.length)) {
    try {
      var query = parser.generate_query_ast_sync(build_query(filters))
    } catch (error) {
      console.log('Invalid query: %s'.red, error.message)
      return
    }

    async.concat(servers, function (server, next) {
      parser.match(JSON.parse(JSON.stringify(server)), query, function (error, matches) {
        next(error, matches ? server : [])
      })
    }, function (error, servers) {
      if (!servers.length) {
        return console.log('No matching servers found'.red)
      }

      display_results(servers)
    })
  } else {
    display_results(servers)
  }
}

var build_query = function (filters) {
  var query = ''

  if (commander.servername) {
    query += build_query_part('name', commander.servername)
  }

  if (commander.region) {
    query += build_query_part('region', commander.region)
  }

  if (commander.hostname) {
    query += build_query_part('hostname', commander.hostname)
  }

  if (commander.image) {
    query += build_query_part('image', commander.image)
  }

  if (commander.ip) {
    query += build_query_part('ip', commander.ip)
  }

  if (commander.id) {
    query += build_query_part('id', commander.id)
  }

  if (filters) {
    query += ' AND (' + filters + ')'
  }

  if (commander.query) {
    if (!query.length) {
      query += commander.query
    } else {
      query += ' AND (' + commander.query + ')'
    }
  }

  if (alias && alias.query) {
    query += ' AND (' + alias.query + ')'
  }

  query = query.trim()

  if (util.starts_with(query, 'AND')) {
    query = query.substring(3)
  }

  if (util.starts_with(query, 'OR')) {
    query = query.substring(2)
  }

  return query.trim()
}

var build_query_part = function (key_name, key) {
  var query = ' AND ('
  var split_count = key.length

  key.forEach(function (split) {
    split_count--

    query += key_name + ' CONTAINS' + ' \'' + split + '\''

    if (split_count) {
      query += ' OR '
    }
  })

  query += ')'

  return query
}

var display_results = function (result) {
  var color_index = 0
  var index = 0

  result.forEach(function (server) {
    require('./plugins/' + server.account.type).display(server, index+++1)
  })

  if (result.length == 1 && config.auto_connect_on_one_result) {
    return prepare_ssh(result[0])
  }

  if (((alias && alias.run_on_all) || commander.run_on_all) && ((alias && alias.command) || commander.ssh_command)) {
    return result.forEach(function (server) {
      prepare_ssh(server, util.colors[color_index++])

      if (color_index > (util.colors.length - 1)) {
        color_index = 0
      }
    })
  }

  var reader = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  })

  reader.question("Which server do you want to connect to? ", function (index) {
    var server = result[index - 1]
    reader.close()

    if (!server) {
      return console.log('Invalid selection'.red)
    }

    prepare_ssh(server)
  })
}

var prepare_ssh = function (server, disable_tt) {
  var ssh_config

  if (!config.ssh_config.length) {
    return console.log('Please specify a default ssh config'.red)
  }

  function iterate_configs (the_config, next) {
    var account_match = false
    var query

    if (the_config.priority === 0) {
      ssh_config = the_config
      return next()
    }

    if (the_config.accounts && (util.contains_with_lowercase(server.account.name.toLowerCase(), the_config.accounts) || (server.account.public_token && util.contains_with_lowercase(server.account.public_token.toLowerCase(), the_config.accounts)))) {
      account_match = true
    }

    if (!the_config.query) {
      if (account_match) {
        if (!ssh_config || the_config.priority > ssh_config.priority) {
          ssh_config = the_config
        }
      }

      return next()
    }

    try {
      query = parser.generate_query_ast_sync(the_config.query)
    } catch (error) {
      return console.log('Invalid ssh config query: %s'.red, error.message)
    }

    parser.match(JSON.parse(JSON.stringify(server)), query, function (error, matches) {
      if (error) {
        return console.log('Error parsing with ssh config query %s'.red, error)
      }

      if (matches) {
        if ((the_config.accounts && account_match) || !the_config.accounts) {
          if (!ssh_config || the_config.priority > ssh_config.priority) {
            ssh_config = the_config
          }
        }
      }

      next(error)
    })
  }

  function next (error) {
    ssh(server, ssh_config, disable_tt)
  }

  async.each(config.ssh_config, iterate_configs, next)
}

var ssh = function (server, ssh_config, disable_tt) {
  // TODO Merge default conf with ssh config, config option?
  if (ssh_config) {
    require('./plugins/' + server.account.type).ssh(server, build_ssh_config(ssh_config, disable_tt))

    return
  }

  console.log('No matching ssh config, please specify a default ssh config'.red)
}

var build_ssh_config = function (ssh_config, disable_tt) {
  var options = {
    user: ssh_config.user,
    port: ssh_config.port,
    keyfile: ssh_config.keyfile,
    command: ssh_config.command,
    disable_tt: disable_tt,
    private_ip: ssh_config.private_ip,
    extra_options: []
  }

  if (alias && alias.user) {
    options.user = alias.user
  }

  if (commander.user) {
    options.user = commander.user
  }

  if (alias && alias.port) {
    options.port = alias.port
  }

  if (commander.port) {
    options.port = commander.port
  }

  if (alias && alias.keyfile) {
    options.keyfile = alias.keyfile
  }

  if (commander.keyfile) {
    options.keyfile = commander.keyfile
  }

  if (alias && alias.command) {
    options.command = alias.command
  }

  if (commander.ssh_command) {
    options.command = commander.ssh_command
  }

  if (alias && alias.private_ip) {
    options.private_ip = true
  }

  if (commander.private_ip) {
    options.private_ip = true
  }

  options.port = options.port ? options.port : 22
  options.user = options.user ? options.user : 'root'

  if (ssh_config.options && ssh_config.options.length) {
    options.extra_options = ssh_config.options
  }

  if (alias && alias.options) {
    options.extra_options = alias.options
  }

  return options
}

// Commands

if (commander.list_accounts) {
  config.credentials.forEach(function (account) {
    console.log('%s %s (%s)' + (account.public_token ? ' - %s' : ''), account.name.green, account.type.blue, colors.yellow(account.regions ? account.regions : require('./plugins/' + account.type).regions), account.public_token ? colors.red(account.public_token) : '')
  })
  return
}

if (commander.keys) {
  try {
    console.log("Keys for %s: %s".white, colors.blue(commander.keys), require('./plugins/' + commander.keys).keys.join(", "))
  } catch (error) {
    console.error('Provided type \'%s\' does not exist'.red, commander.keys)
  }
  return
}

parse_arguments()<|endoftext|>


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

/**
 * Create a new StatsPlugin that causes webpack to generate a stats file as
 * part of the emitted assets.
 * @constructor
 * @param {String} output Path to output file.
 * @param {Object} options Options passed to the stats' `.toJson()`.
 */
function StatsPlugin (output, options, cache) {
  this.output = output
  this.options = options
  this.cache = cache || {}
}

StatsPlugin.prototype.apply = function apply (compiler) {
  var output = this.output
  var options = this.options
  var cache = this.cache

  compiler.plugin('emit', function onEmit (compilation, done) {
    var result

    compilation.assets[output] = {
      size: function getSize () {
        return result && result.length || 0
      },
      source: function getSource () {
        var stats = compilation.getStats().toJson(options)
        cache = _.merge(cache, stats)
        result = JSON.stringify(cache)
        return result
      }
    }
    done()
  })
}

module.exports = StatsPlugin
<commit_msg>Disable default caching<commit_after>var _ = require('lodash')

/**
 * Create a new StatsPlugin that causes webpack to generate a stats file as
 * part of the emitted assets.
 * @constructor
 * @param {String} output Path to output file.
 * @param {Object} options Options passed to the stats' `.toJson()`.
 */

function StatsPlugin (output, options, cache) {
  this.output = output
  this.options = options
  this.cache = cache
}

StatsPlugin.prototype.apply = function apply (compiler) {
  var output = this.output
  var options = this.options
  var cache = this.cache

  compiler.plugin('emit', function onEmit (compilation, done) {
    var result

    compilation.assets[output] = {
      size: function getSize () {
        return result && result.length || 0
      },
      source: function getSource () {
        var stats = compilation.getStats().toJson(options)
        var result

        if (cache) {
          cache = _.merge(cache, stats)
          result = JSON.stringify(cache)
        } else {
          result = JSON.stringify(stats)
        }
        return result
      }
    }
    done()
  })
}

module.exports = StatsPlugin
<|endoftext|>


<commit_before>/*!
 * paginationator <https://github.com/doowb/paginationator>
 *
 * Copyright (c) 2015, Brian Woodward.
 * Licensed under the MIT License.
 */

'use strict';

var Pages = require('./lib/pages');
var Page = require('./lib/page');

/**
 * Paginate an array with given options and return a `Page` object
 * containing an array of `pages` with pagination information.
 *
 * ```js
 * var pages = paginationator([1, 2, 3, 4, 5], {limit: 2});
 * //=> { pages: [
 * //=>   { idx: 0, total: 3, current: 1, items: [1, 2], first: 1, last: 3, next: 2 },
 * //=>   { idx: 1, total: 3, current: 2, items: [3, 4], first: 1, last: 3, prev: 1, next: 3 },
 * //=>   { idx: 2, total: 3, current: 3, items: [5], first: 1, last: 3, prev: 2 }
 * //=> ]}
 * ```
 *
 * @param  {Array}  `arr` Array of items to paginate
 * @param  {Object} `options` Additional options to control pagination
 * @param  {Number} `options.limit` Number of items per page (defaults to 10)
 * @return {Object} paginated pages
 * @api public
 * @name  paginationator
 */

module.exports = function paginationator(arr, options) {
  if (!Array.isArray(arr)) {
    throw new TypeError('expected arr to be an Array');
  }
  options = options || {};
  var limit = options.limit || 10;
  var total = Math.ceil(arr.length / limit);
  var i = 0;

  var pages = new Pages(), page = new Page();
  while (i < total) {
    var start = i * limit;
    var end = start + limit;
    page.items = arr.slice(start, end);
    pages.addPage(page);
    i++;
    page = new Page();
  }
  return pages;
};

/**
 * Expose `Pages`
 */

module.exports.Pages = Pages;

/**
 * Expose `Page`
 */

module.exports.Page = Page;
<commit_msg>create page inside loop<commit_after>/*!
 * paginationator <https://github.com/doowb/paginationator>
 *
 * Copyright (c) 2015, Brian Woodward.
 * Licensed under the MIT License.
 */

'use strict';

var Pages = require('./lib/pages');
var Page = require('./lib/page');

/**
 * Paginate an array with given options and return a `Page` object
 * containing an array of `pages` with pagination information.
 *
 * ```js
 * var pages = paginationator([1, 2, 3, 4, 5], {limit: 2});
 * //=> { pages: [
 * //=>   { idx: 0, total: 3, current: 1, items: [1, 2], first: 1, last: 3, next: 2 },
 * //=>   { idx: 1, total: 3, current: 2, items: [3, 4], first: 1, last: 3, prev: 1, next: 3 },
 * //=>   { idx: 2, total: 3, current: 3, items: [5], first: 1, last: 3, prev: 2 }
 * //=> ]}
 * ```
 *
 * @param  {Array}  `arr` Array of items to paginate
 * @param  {Object} `options` Additional options to control pagination
 * @param  {Number} `options.limit` Number of items per page (defaults to 10)
 * @return {Object} paginated pages
 * @api public
 * @name  paginationator
 */

module.exports = function paginationator(arr, options) {
  if (!Array.isArray(arr)) {
    throw new TypeError('expected arr to be an Array');
  }
  options = options || {};
  var limit = options.limit || 10;
  var total = Math.ceil(arr.length / limit);
  var i = 0;

  var pages = new Pages();
  while (i < total) {
    var page = new Page();
    var start = i * limit;
    var end = start + limit;
    page.items = arr.slice(start, end);
    pages.addPage(page);
    i++;
  }
  return pages;
};

/**
 * Expose `Pages`
 */

module.exports.Pages = Pages;

/**
 * Expose `Page`
 */

module.exports.Page = Page;
<|endoftext|>


<commit_before>/*
Daefen
------

A library for encoding/decoding large numbers into/from a pronounceable high-density string constructed from a base of 3456 syllables.

*/

// Creates the syllable array
var syllables = [];
var consonants = 'bcdfghjklmnprstvwz'; // consonants that are unambiguous and easy to pronounce
var vowels = 'aeiouy'; // vowels

// Vowel + Consonant
for (a = 0; a < vowels.length; a++) {
  for (b = 0; b < consonants.length; b++) {
    syllables.push(vowels[a] + consonants[b] );
  }
}

// Consonant + Vowel
for (b = 0; b < consonants.length; b++) {
  for (a = 0; a < vowels.length; a++) {
    syllables.push(consonants[b] + vowels[a]);
  }
}

// Consonant + Vowel + Vowel
for (b = 0; b < consonants.length; b++) {
  for (a = 0; a < vowels.length; a++) {
    for (e = 0; e < vowels.length; e++) {
      syllables.push(consonants[b] + vowels[a] + vowels[e]);
    }
  }
}

// Consonant + Vowel + Consonant
for (b = 0; b < consonants.length; b++) {
  for (a = 0; a < vowels.length; a++) {
    for (c = 0; c < consonants.length; c++) {
      syllables.push(consonants[b] + vowels[a] + consonants[c]);
    }
  }
}

// Vowel + Consonant + Vowel
for (a = 0; a < vowels.length; a++) {
  for (b = 0; b < consonants.length; b++) {
    for (e = 0; e < vowels.length; e++) {
      syllables.push(vowels[a] + consonants[b] + vowels[e]);
    }
  }
}

// Quick function that converts a big Number object into an array of numbers for any chosen base
function fromBase10(bigNum, base) {
  var result = [];
  if (bigNum == 0) return [0];
  for (var i=bigNum; i > 0; i = i.dividedBy(base).floor()){
   result.unshift(i.modulo(base).toFixed());
  };
  return result;
}

// Important to check some spacing issues
function isConsonant(letter) {
  return consonants.indexOf(letter) >= 0;
}

// Converts an integer (passed as a string to avoid scientific notation issues)
function toWords(numberAsString) {
  let bn = new BigNumber(numberAsString.toString());
  let numberArray = fromBase10(bn, syllables.length);
  let result = '';
  let lastWord = '';
  let n = 0;
  for (i = 0; i < numberArray.length; i++) {
    n = numberArray[i] || 0;

    lastWord = result.split(" ").slice(-1)[0];

    if (result == ''  || lastWord.length == syllables[n].length
      || (lastWord.length < 5 && isConsonant(lastWord.slice(-1)) && isConsonant(syllables[n].slice(0,1))) ) {
      result += syllables[n];
    } else {
      result += " " + syllables[n];
    }
  }
  return result.replace(/\b[a-z]/g,function(f){return f.toUpperCase();});
}

// Converts a valid phrase back into a string
function fromWords(words) {
  let wordArray = words.toLowerCase()
    .replace(/[bcdfghjklmnprstvwz][bcdfghjklmnprstvwz]/gi,function(r){ let n = Math.floor(r.length/2); return r.substr(0,n) + ' ' + r.substr(n,n)})
    .replace(/[a-z]{6}|[a-z]{4}/gi,function(r){ let n = Math.floor(r.length/2); return r.substr(0,n) + ' ' + r.substr(n,n)})
    .split(" ");
  let result = new BigNumber(0);

  for (i = 0; i < wordArray.length; i++) {
    if (syllables.indexOf(wordArray[i]) < 0) return;
    result = result.plus(new BigNumber(syllables.indexOf(wordArray[i])).times(new BigNumber(syllables.length).toPower(wordArray.length - i - 1)))
  }

  return result.toString(10);
}

var random = Math.floor(Math.random()*Math.pow(3456,5)).toString()
toWords(random)

<commit_msg>remove bignum<commit_after>/*
Daefen
------
A library for encoding/decoding large numbers into/from a pronounceable high-density string constructed from a base of 3456 syllables.

*/

// Creates the syllable array
var syllables = [];
var consonants = "bcdfghjklmnprstvwz"; // consonants that are unambiguous and easy to pronounce
var vowels = "aeiouy"; // vowels

// Vowel + Consonant
for (a = 0; a < vowels.length; a++) {
  for (b = 0; b < consonants.length; b++) {
    syllables.push(vowels[a] + consonants[b]);
  }
}

// Consonant + Vowel
for (b = 0; b < consonants.length; b++) {
  for (a = 0; a < vowels.length; a++) {
    syllables.push(consonants[b] + vowels[a]);
  }
}

// Consonant + Vowel + Vowel
for (b = 0; b < consonants.length; b++) {
  for (a = 0; a < vowels.length; a++) {
    for (e = 0; e < vowels.length; e++) {
      syllables.push(consonants[b] + vowels[a] + vowels[e]);
    }
  }
}

// Consonant + Vowel + Consonant
for (b = 0; b < consonants.length; b++) {
  for (a = 0; a < vowels.length; a++) {
    for (c = 0; c < consonants.length; c++) {
      syllables.push(consonants[b] + vowels[a] + consonants[c]);
    }
  }
}

// Vowel + Consonant + Vowel
for (a = 0; a < vowels.length; a++) {
  for (b = 0; b < consonants.length; b++) {
    for (e = 0; e < vowels.length; e++) {
      syllables.push(vowels[a] + consonants[b] + vowels[e]);
    }
  }
}

// Quick function that converts a big Number object into an array of numbers for any chosen base
function fromBase10(bigNum, base) {
  var result = [];
  if (bigNum == 0) return [0];
  for (var i = bigNum; i > 0; i = Math.floor(i / base)) {
    result.unshift(i % base);
  }
  return result;
}

// Important to check some spacing issues
function isConsonant(letter) {
  return consonants.indexOf(letter) >= 0;
}

// Converts an integer (passed as a string to avoid scientific notation issues)
function toWords(number) {
  let numberArray = fromBase10(number, syllables.length);
  let result = "";
  let lastWord = "";
  let n = 0;
  for (i = 0; i < numberArray.length; i++) {
    n = numberArray[i] || 0;

    lastWord = result.split(" ").slice(-1)[0];

    if (
      result == "" ||
      lastWord.length == syllables[n].length ||
      (lastWord.length < 5 &&
        isConsonant(lastWord.slice(-1)) &&
        isConsonant(syllables[n].slice(0, 1)))
    ) {
      result += syllables[n];
    } else {
      result += " " + syllables[n];
    }
  }
  return result.replace(/\b[a-z]/g, function(f) {
    return f.toUpperCase();
  });
}

// Converts a valid phrase back into a string
function fromWords(words) {
  let wordArray = words
    .toLowerCase()
    .replace(/[bcdfghjklmnprstvwz][bcdfghjklmnprstvwz]/gi, function(r) {
      let n = Math.floor(r.length / 2);
      return r.substr(0, n) + " " + r.substr(n, n);
    })
    .replace(/[a-z]{6}|[a-z]{4}/gi, function(r) {
      let n = Math.floor(r.length / 2);
      return r.substr(0, n) + " " + r.substr(n, n);
    })
    .split(" ");
  let result = 0;

  for (i = 0; i < wordArray.length; i++) {
    if (syllables.indexOf(wordArray[i]) < 0) return;

    result =
      result +
      syllables.indexOf(wordArray[i]) *
        Math.pow(syllables.length, wordArray.length - i - 1);
  }

  return result;
}

var random = Math.floor(Math.random() * Math.pow(2, 55));

toWords(random);
<|endoftext|>


<commit_before>module.exports = {
  "rules": {
    "at-rule-empty-line-before": [ "always", {
      except: [ "blockless-group", "first-nested" ],
      ignore: ["after-comment"],
    } ],
    "block-closing-brace-newline-after": "always",
    "block-closing-brace-newline-before": "always-multi-line",
    "block-closing-brace-space-before": "always-single-line",
    "block-no-empty": true,
    "block-opening-brace-newline-after": "always-multi-line",
    "block-opening-brace-space-after": "always-single-line",
    "block-opening-brace-space-before": "always",
    "color-hex-case": "lower",
    "color-hex-length": "short",
    "color-no-invalid-hex": true,
    "comment-empty-line-before": [ "always", {
      except: ["first-nested"],
      ignore: ["stylelint-commands"],
    } ],
    "comment-whitespace-inside": "always",
    "declaration-bang-space-after": "never",
    "declaration-bang-space-before": "always",
    "declaration-block-no-duplicate-properties": true,
    "declaration-block-no-shorthand-property-overrides": true,
    "declaration-block-semicolon-newline-after": "always-multi-line",
    "declaration-block-semicolon-space-after": "always-single-line",
    "declaration-block-semicolon-space-before": "never",
    "declaration-block-single-line-max-declarations": 1,
    "declaration-block-trailing-semicolon": "always",
    "declaration-colon-newline-after": "always-multi-line",
    "declaration-colon-space-after": "always-single-line",
    "declaration-colon-space-before": "never",
    "font-family-name-quotes": "single-where-recommended",
    "function-calc-no-unspaced-operator": true,
    "function-comma-newline-after": "always-multi-line",
    "function-comma-space-after": "always-single-line",
    "function-comma-space-before": "never",
    "function-linear-gradient-no-nonstandard-direction": true,
    "function-parentheses-newline-inside": "always-multi-line",
    "function-parentheses-space-inside": "never-single-line",
    "function-whitespace-after": "always",
    "indentation": 2,
    "max-empty-lines": 2,
    "media-feature-colon-space-after": "always",
    "media-feature-colon-space-before": "never",
    "media-feature-no-missing-punctuation": true,
    "media-feature-range-operator-space-after": "always",
    "media-feature-range-operator-space-before": "always",
    "media-query-list-comma-newline-after": "always-multi-line",
    "media-query-list-comma-space-after": "always-single-line",
    "media-query-list-comma-space-before": "never",
    "media-query-parentheses-space-inside": "never",
    "no-eol-whitespace": true,
    "no-invalid-double-slash-comments": true,
    "no-missing-eof-newline": true,
    "number-leading-zero": "always",
    "number-no-trailing-zeros": true,
    "number-zero-length-no-unit": true,
    "rule-non-nested-empty-line-before": [ "always-multi-line", {
      ignore: ["after-comment"],
    } ],
    "selector-combinator-space-after": "always",
    "selector-combinator-space-before": "always",
    "selector-list-comma-newline-after": "always",
    "selector-list-comma-space-before": "never",
    "selector-pseudo-element-colon-notation": "single",
    "string-no-newline": true,
    "string-quotes": "single",
    "value-list-comma-newline-after": "always-multi-line",
    "value-list-comma-space-after": "always-single-line",
    "value-list-comma-space-before": "never",
  }
};
<commit_msg>enforce alphabetizing keys<commit_after>module.exports = {
  "rules": {
    "at-rule-empty-line-before": [ "always", {
      except: [ "blockless-group", "first-nested" ],
      ignore: ["after-comment"],
    } ],
    "block-closing-brace-newline-after": "always",
    "block-closing-brace-newline-before": "always-multi-line",
    "block-closing-brace-space-before": "always-single-line",
    "block-no-empty": true,
    "block-opening-brace-newline-after": "always-multi-line",
    "block-opening-brace-space-after": "always-single-line",
    "block-opening-brace-space-before": "always",
    "color-hex-case": "lower",
    "color-hex-length": "short",
    "color-no-invalid-hex": true,
    "comment-empty-line-before": [ "always", {
      except: ["first-nested"],
      ignore: ["stylelint-commands"],
    } ],
    "comment-whitespace-inside": "always",
    "declaration-bang-space-after": "never",
    "declaration-bang-space-before": "always",
    "declaration-block-no-duplicate-properties": true,
    "declaration-block-no-shorthand-property-overrides": true,
    "declaration-block-properties-order": "alphabetical",
    "declaration-block-semicolon-newline-after": "always-multi-line",
    "declaration-block-semicolon-space-after": "always-single-line",
    "declaration-block-semicolon-space-before": "never",
    "declaration-block-single-line-max-declarations": 1,
    "declaration-block-trailing-semicolon": "always",
    "declaration-colon-newline-after": "always-multi-line",
    "declaration-colon-space-after": "always-single-line",
    "declaration-colon-space-before": "never",
    "font-family-name-quotes": "single-where-recommended",
    "function-calc-no-unspaced-operator": true,
    "function-comma-newline-after": "always-multi-line",
    "function-comma-space-after": "always-single-line",
    "function-comma-space-before": "never",
    "function-linear-gradient-no-nonstandard-direction": true,
    "function-parentheses-newline-inside": "always-multi-line",
    "function-parentheses-space-inside": "never-single-line",
    "function-whitespace-after": "always",
    "indentation": 2,
    "max-empty-lines": 2,
    "media-feature-colon-space-after": "always",
    "media-feature-colon-space-before": "never",
    "media-feature-no-missing-punctuation": true,
    "media-feature-range-operator-space-after": "always",
    "media-feature-range-operator-space-before": "always",
    "media-query-list-comma-newline-after": "always-multi-line",
    "media-query-list-comma-space-after": "always-single-line",
    "media-query-list-comma-space-before": "never",
    "media-query-parentheses-space-inside": "never",
    "no-eol-whitespace": true,
    "no-invalid-double-slash-comments": true,
    "no-missing-eof-newline": true,
    "number-leading-zero": "always",
    "number-no-trailing-zeros": true,
    "number-zero-length-no-unit": true,
    "rule-non-nested-empty-line-before": [ "always-multi-line", {
      ignore: ["after-comment"],
    } ],
    "selector-combinator-space-after": "always",
    "selector-combinator-space-before": "always",
    "selector-list-comma-newline-after": "always",
    "selector-list-comma-space-before": "never",
    "selector-pseudo-element-colon-notation": "single",
    "string-no-newline": true,
    "string-quotes": "single",
    "value-list-comma-newline-after": "always-multi-line",
    "value-list-comma-space-after": "always-single-line",
    "value-list-comma-space-before": "never",
  }
};
<|endoftext|>


<commit_before>var Url = require ("url")
  , Fs  = require ("fs")
  , Path = require("path")
  ;

const MIME_TYPES = {
    "html": "text/html"
  , "jpeg": "image/jpeg"
  , "jpg":  "image/jpeg"
  , "png":  "image/png"
  , "js":   "text/javascript"
  , "css":  "text/css"
};

var Statique = {
    server: function (options) {
        if (typeof options === "string") {
            options = {
                root: options
            }
        }
        if (options.root.slice (-1) !== "/") {
            options.root += "/";
        }

        Statique._root = options.root;
        return Statique;
    }
  , setRoutes: function (routes) {
        Statique._routes = routes;
        return Statique;
    }
  , getRoute: function (url) {
        return Statique._routes[url] || Statique._routes[url + "/"] || null;
    }
  , exists: function (req, res) {
        return Boolean (Statique.getRoute(Url.parse(req.url).pathname));
    }
  , readFile: function (file, callback) {
        return fs.readFile (Statique._root + file, function (err, buffer) {
            if (err) { return callback (err); }
            callback (null, buffer.toString())
        });
    }
  , serve: function (req, res) {

        var parsedUrl = Url.parse (req.url)
          , route = Statique.getRoute (parsedUrl.pathname) || parsedUrl.pathname
          , stats = null
          , fileName = Statique._root + route
          ;

        try {
            stats = Fs.lstatSync (fileName);
        } catch (e) {
            Statique.sendRes (res, 404, "html", "404 - Not found");
            return;
        }

        if (stats.isFile()) {
            Statique.sendRes(res, 200, MIME_TYPES[Path.extname(route).substring(1)]);
            var fileStream = Fs.createReadStream(fileName);
            fileStream.pipe(res);
        }
    }
  , sendRes: function (res, statusCode, mimeType, content) {

        res.writeHead(statusCode, {
            "Content-Type": mimeType || "plain/text"
          , "Server": "Statique Server"
        });

        if (typeof content === "string") {
            res.end (content);
        }
    }
};

// export the module
module.exports = Statique;
<commit_msg>Fixed typo<commit_after>var Url = require ("url")
  , Fs  = require ("fs")
  , Path = require("path")
  ;

const MIME_TYPES = {
    "html": "text/html"
  , "jpeg": "image/jpeg"
  , "jpg":  "image/jpeg"
  , "png":  "image/png"
  , "js":   "text/javascript"
  , "css":  "text/css"
};

var Statique = {
    server: function (options) {
        if (typeof options === "string") {
            options = {
                root: options
            }
        }
        if (options.root.slice (-1) !== "/") {
            options.root += "/";
        }

        Statique._root = options.root;
        return Statique;
    }
  , setRoutes: function (routes) {
        Statique._routes = routes;
        return Statique;
    }
  , getRoute: function (url) {
        return Statique._routes[url] || Statique._routes[url + "/"] || null;
    }
  , exists: function (req, res) {
        return Boolean (Statique.getRoute(Url.parse(req.url).pathname));
    }
  , readFile: function (file, callback) {
        return Fs.readFile (Statique._root + file, function (err, buffer) {
            if (err) { return callback (err); }
            callback (null, buffer.toString())
        });
    }
  , serve: function (req, res) {

        var parsedUrl = Url.parse (req.url)
          , route = Statique.getRoute (parsedUrl.pathname) || parsedUrl.pathname
          , stats = null
          , fileName = Statique._root + route
          ;

        try {
            stats = Fs.lstatSync (fileName);
        } catch (e) {
            Statique.sendRes (res, 404, "html", "404 - Not found");
            return;
        }

        if (stats.isFile()) {
            Statique.sendRes(res, 200, MIME_TYPES[Path.extname(route).substring(1)]);
            var fileStream = Fs.createReadStream(fileName);
            fileStream.pipe(res);
        }
    }
  , sendRes: function (res, statusCode, mimeType, content) {

        res.writeHead(statusCode, {
            "Content-Type": mimeType || "plain/text"
          , "Server": "Statique Server"
        });

        if (typeof content === "string") {
            res.end (content);
        }
    }
};

// export the module
module.exports = Statique;
<|endoftext|>


<commit_before>var express = require('express');
var request = require('request');
var bodyParser = require('body-parser');
var cron = require('node-cron');
var cheerio = require('cheerio');

var app = express();
app.listen((process.env.PORT || 3000));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

// Current version
ver = 'v.0.0.14';
// Facebook pageId
pageId = '1167308473348175';
// My user on Facebook
me = '100000522710505';

// Server endpoint
app.get('/', function (req, res) {
    res.send('JKDbot here! ' + ver);
});

// Facebook webhook
app.get('/webhook', function (req, res) {
    if (req.query['hub.verify_token'] === 'jkdbot_verify_token') {
        res.send(req.query['hub.challenge']);
    } else {
        res.send('Invalid verify token');
    }
});

// Handler receiving messages
app.post('/webhook', function (req, res) {
    var events = req.body.entry[0].messaging;
    for (i = 0; i < events.length; i++) {
        var event = events[i];
        if (event.message && event.message.text) {
            switch(event.message.text) {
                case("cmd_version"):
                    sendMessage(event.sender.id, {text: ver});
                    break;
                case("cmd_subscribers"):
                    sendMessage(event.sender.id, {text: getUserIds()});
                    break;
                case("cmd_timezone"):
                    sendMessage(event.sender.id, {text: getUserTimezone("1")});
                    break;
                default:
                    sendMessage(event.sender.id, {text: "Message received: " + event.message.text + " by " + event.sender.id});
                    break;
            }
        }
    }
    res.sendStatus(200);
});

// Scheduler
var job = cron.job('*/2 * * * *', function() {
    console.log('Running sendout');
    doSendout();
});
job.start();

// Main task
var doSendout = function() {
    sendMessage(me, {text: "jkdbot here"});
}

// Sends a message to a Facebook user
var sendMessage = function(recipientId, message) {
    request({
        url: 'https://graph.facebook.com/v2.8/me/messages',
        qs: {access_token: process.env.PAGE_ACCESS_TOKEN},
        method: 'POST',
        json: {
            recipient: {id: recipientId},
            message: message,
        }
    }, function(error, response, html) {
        if (error) {
            console.log('Error sending message: ', error);
        } else if (response.body.error) {
            console.log('Error: ', response.body.error);
        }
    });
};

// Facebook page with the likes of our app
var url = 'https://www.facebook.com/browse/?type=page_fans&page_id='+pageId;
// Collects the userId's from the page likes html
var getUserIds = function() {
    var userIds = [];
    request(url, function (error, response, body) {
    if (!error && response.statusCode == 200) {
        var $ = cheerio.load(body);
        $('a[data-gt]').each(function(i, a) {
            var gt = JSON.parse(a.dataset.gt);
            if(!gt.engagement || gt.engagement.eng_type !== "1") {
                return;
            }
            console.log(gt.engagement.eng_tid);
            userIds.push(gt.engagement.eng_tid)
        });
    } else {
        console.log('Error retrieving likes: ', error);
    }
    });
};

// Retrieves the timezone of a user
var getUserTimezone = function(userId) {
    return "-9";
};
<commit_msg>Scheduler<commit_after>var express = require('express');
var request = require('request');
var bodyParser = require('body-parser');
var cron = require('node-cron');
var cheerio = require('cheerio');

var app = express();
app.listen((process.env.PORT || 3000));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

// Current version
ver = 'v.0.0.15';
// Facebook pageId
pageId = '1167308473348175';
// My user on Facebook
me = '100000522710505';

// Server endpoint
app.get('/', function (req, res) {
    res.send('JKDbot here! ' + ver);
});

// Facebook webhook
app.get('/webhook', function (req, res) {
    if (req.query['hub.verify_token'] === 'jkdbot_verify_token') {
        res.send(req.query['hub.challenge']);
    } else {
        res.send('Invalid verify token');
    }
});

// Handler receiving messages
app.post('/webhook', function (req, res) {
    var events = req.body.entry[0].messaging;
    for (i = 0; i < events.length; i++) {
        var event = events[i];
        if (event.message && event.message.text) {
            switch(event.message.text) {
                case("cmd_version"):
                    sendMessage(event.sender.id, {text: ver});
                    break;
                case("cmd_subscribers"):
                    sendMessage(event.sender.id, {text: getUserIds()});
                    break;
                case("cmd_timezone"):
                    sendMessage(event.sender.id, {text: getUserTimezone("1")});
                    break;
              case("cmd_stop_cron"):
                    task.stop();
                    break;
                default:
                    sendMessage(event.sender.id, {text: "Message received: " + event.message.text + " by " + event.sender.id});
                    break;
            }
        }
    }
    res.sendStatus(200);
});

// Scheduler
var task = cron.schedule('*/2 * * * *', function() {
    console.log('Running sendout');
    doSendout();
});
task.start();

// Main task
var doSendout = function() {
    sendMessage(me, {text: "jkdbot here"});
}

// Sends a message to a Facebook user
var sendMessage = function(recipientId, message) {
    request({
        url: 'https://graph.facebook.com/v2.8/me/messages',
        qs: {access_token: process.env.PAGE_ACCESS_TOKEN},
        method: 'POST',
        json: {
            recipient: {id: recipientId},
            message: message,
        }
    }, function(error, response, html) {
        if (error) {
            console.log('Error sending message: ', error);
        } else if (response.body.error) {
            console.log('Error: ', response.body.error);
        }
    });
};

// Facebook page with the likes of our app
var url = 'https://www.facebook.com/browse/?type=page_fans&page_id='+pageId;
// Collects the userId's from the page likes html
var getUserIds = function() {
    var userIds = [];
    request(url, function (error, response, body) {
    if (!error && response.statusCode == 200) {
        var $ = cheerio.load(body);
        $('a[data-gt]').each(function(i, a) {
            var gt = JSON.parse(a.dataset.gt);
            if(!gt.engagement || gt.engagement.eng_type !== "1") {
                return;
            }
            console.log(gt.engagement.eng_tid);
            userIds.push(gt.engagement.eng_tid)
        });
    } else {
        console.log('Error retrieving likes: ', error);
    }
    });
};

// Retrieves the timezone of a user
var getUserTimezone = function(userId) {
    return "-9";
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';

//

var templates = {
  'package-template.json': '/',
  'index.html': 'www/',
  'config-template.xml': '/',
  'ionic.config.json': '/',
  '.desktop': 'webkitbuilds/',
  'setup-win.iss': 'webkitbuilds/',
  'build-macos.sh': 'webkitbuilds/',
  'manifest.json': 'chrome-app/',
  //  'bower.json': '/',
};
var configDir = process.argv[2] || 'copay';
var JSONheader = ' { ' + "\n" + '  "//":"Changes to this file will be overwritten",' + "\n" + '  "//":"        Modify it in the app-template directory", ' + "\n";

var MakefileHeader = "# PLEASE! Do not edit this file directly \n#       Modify it at app-template/\n";

var fs = require('fs-extra');
var path = require('path');

var configBlob = fs.readFileSync(configDir + '/appConfig.json', 'utf8');
var config = JSON.parse(configBlob, 'utf8');

/////////////////
console.log('Applying ' + config.nameCase + ' template');

Object.keys(templates).forEach(function(k) {
  var targetDir = templates[k];
  console.log(' #    ' + k + ' => ' + targetDir);

  var content = fs.readFileSync(k, 'utf8');

  if (k.indexOf('.json') > 0) {
    content = content.replace('{', JSONheader);

  } else if (k.indexOf('Makefile') >= 0) {
    content = MakefileHeader + content;
  }

  Object.keys(config).forEach(function(k) {
    if (k.indexOf('_') == 0) return;

    var r = new RegExp("\\*" + k.toUpperCase() + "\\*", "g");
    content = content.replace(r, config[k]);
  });

  var r = new RegExp("\\*[A-Z]{3,30}\\*", "g");
  var s = content.match(r);
  if (s) {
    console.log('UNKNOWN VARIABLE', s);
    process.exit(1);
  }

  if(k === 'config-template.xml'){
    k = 'config.xml';
  } else if (k === 'package-template.json') {
    k = 'package.json';
  }

  if (!fs.existsSync('../' + targetDir)){
    fs.mkdirSync('../' + targetDir);
  }
  fs.writeFileSync('../' + targetDir + k, content, 'utf8');
});

/////////////////
console.log('Copying ' + configDir + '/appConfig.json' + ' to root');
configBlob = configBlob.replace('{', JSONheader);
fs.writeFileSync('../appConfig.json', configBlob, 'utf8');

////////////////
var externalServices;
try {
  var confName = configDir.toUpperCase();
  var externalServicesConf = confName + '_EXTERNAL_SERVICES_CONFIG_LOCATION';
  console.log('Looking for ' + externalServicesConf + '...');
  if(typeof process.env[externalServicesConf] !== 'undefined') {
    var location = process.env[externalServicesConf]
    if(location.charAt(0) === '~') {
      location = location.replace(/^\~/, process.env.HOME || process.env.USERPROFILE);
    }
    console.log('Found at: ' + location);
    console.log('Copying ' + location + ' to root');
    externalServices = fs.readFileSync(location, 'utf8');
  } else {
    throw externalServicesConf + ' environment variable not set.';
  }
} catch(err) {
  console.log(err);
  externalServices = '{}';
  console.log('External services not configured');
}
fs.writeFileSync('../externalServices.json', externalServices, 'utf8');

function copyDir(from, to, cb) {
  console.log('Copying dir ' + from + ' to ' + to);
  if (fs.existsSync(to)) fs.removeSync(to); // remove previous app directory
  if (!fs.existsSync(from)) return; // nothing to do
  var files = [];
  fs.walk(from)
    .on('data', function(item) {
      if ((item.stats["mode"] & 0x4000)) {

        var tmp = item.path + '/';
        var l = tmp.length - from.length;
        if (tmp.indexOf(from) == l) return; // #same dir

      }
      if (item.path.indexOf('DS_Store') >= 0) return;

      if (!files.includes(path.dirname(item.path))) {
        files.push(item.path);
      }
    })
    .on('end', function() {
      files.forEach(function(i) {
        console.log(' #    ' + i);
        fs.copySync(i, to + path.basename(i));
      });
      return cb();

    })

}

// Push Notification
fs.copySync(configDir + '/GoogleService-Info.plist', '../GoogleService-Info.plist');
fs.copySync(configDir + '/google-services.json', '../google-services.json');

copyDir(configDir + '/img/', '../www/img/app/', function() {
  copyDir(configDir + '/sass/', '../src/sass/app/', function() {
    console.log("apply.js finished. \n\n");
  });
});
<commit_msg>fix apply on windows os<commit_after>#!/usr/bin/env node

'use strict';

//

var templates = {
  'package-template.json': '/',
  'index.html': 'www/',
  'config-template.xml': '/',
  'ionic.config.json': '/',
  '.desktop': 'webkitbuilds/',
  'setup-win.iss': 'webkitbuilds/',
  'build-macos.sh': 'webkitbuilds/',
  'manifest.json': 'chrome-app/',
  //  'bower.json': '/',
};
var configDir = process.argv[2] || 'copay';
var JSONheader = ' { ' + "\n" + '  "//":"Changes to this file will be overwritten",' + "\n" + '  "//":"        Modify it in the app-template directory", ' + "\n";

var MakefileHeader = "# PLEASE! Do not edit this file directly \n#       Modify it at app-template/\n";

var fs = require('fs-extra');
var path = require('path');

var configBlob = fs.readFileSync(configDir + '/appConfig.json', 'utf8');
var config = JSON.parse(configBlob, 'utf8');

/////////////////
console.log('Applying ' + config.nameCase + ' template');

Object.keys(templates).forEach(function(k) {
  var targetDir = templates[k];
  console.log(' #    ' + k + ' => ' + targetDir);

  var content = fs.readFileSync(k, 'utf8');

  if (k.indexOf('.json') > 0) {
    content = content.replace('{', JSONheader);

  } else if (k.indexOf('Makefile') >= 0) {
    content = MakefileHeader + content;
  }

  Object.keys(config).forEach(function(k) {
    if (k.indexOf('_') == 0) return;

    var r = new RegExp("\\*" + k.toUpperCase() + "\\*", "g");
    content = content.replace(r, config[k]);
  });

  var r = new RegExp("\\*[A-Z]{3,30}\\*", "g");
  var s = content.match(r);
  if (s) {
    console.log('UNKNOWN VARIABLE', s);
    process.exit(1);
  }

  if (k === 'config-template.xml') {
    k = 'config.xml';
  } else if (k === 'package-template.json') {
    k = 'package.json';
  }

  if (!fs.existsSync('../' + targetDir)) {
    fs.mkdirSync('../' + targetDir);
  }
  fs.writeFileSync('../' + targetDir + k, content, 'utf8');
});

/////////////////
console.log('Copying ' + configDir + '/appConfig.json' + ' to root');
configBlob = configBlob.replace('{', JSONheader);
fs.writeFileSync('../appConfig.json', configBlob, 'utf8');

////////////////
var externalServices;
try {
  var confName = configDir.toUpperCase();
  var externalServicesConf = confName + '_EXTERNAL_SERVICES_CONFIG_LOCATION';
  console.log('Looking for ' + externalServicesConf + '...');
  if (typeof process.env[externalServicesConf] !== 'undefined') {
    var location = process.env[externalServicesConf]
    if (location.charAt(0) === '~') {
      location = location.replace(/^\~/, process.env.HOME || process.env.USERPROFILE);
    }
    console.log('Found at: ' + location);
    console.log('Copying ' + location + ' to root');
    externalServices = fs.readFileSync(location, 'utf8');
  } else {
    throw externalServicesConf + ' environment variable not set.';
  }
} catch (err) {
  console.log(err);
  externalServices = '{}';
  console.log('External services not configured');
}
fs.writeFileSync('../externalServices.json', externalServices, 'utf8');

function copyDir(from, to, cb) {
  console.log('Copying dir ' + from + ' to ' + to);
  if (fs.existsSync(to)) fs.removeSync(to); // remove previous app directory
  if (!fs.existsSync(from)) return; // nothing to do
  var files = [];
  fs.walk(from)
    .on('data', function(item) {
      if ((item.stats["mode"] & 0x4000)) {

        var tmp = item.path + '/';
        var l = tmp.length - from.length;
        if (tmp.indexOf(from) == l) return; // #same dir

      }
      if (item.path.indexOf('DS_Store') >= 0) return;

      if (!files.includes(path.dirname(item.path))) {
        files.push(item.path);
      }
    })
    .on('end', function() {
      files.forEach(function(i) {
        console.log(' #    ' + i);
        fs.copySync(i, to);
      })
      return cb();

    })

}

// Push Notification
fs.copySync(configDir + '/GoogleService-Info.plist', '../GoogleService-Info.plist');
fs.copySync(configDir + '/google-services.json', '../google-services.json');

copyDir(configDir + '/img', '../www/img/app', function() {
  copyDir(configDir + '/saas', '../src/sass/app', function() {
    console.log("apply.js finished. \n\n");
  });
});
<|endoftext|>


<commit_before>module.exports = {
	up: function(migration, DataTypes, done) {
		migration.createTable('Incrementals', {
			timestamp: {
				type: DataTypes.DATE,
				notNull: true,
			},
			filename: {
				type: DataTypes.STRING(255),
				notEmpty: true,
			},
			md5sum: {
				type: DataTypes.STRING(32),
				notEmpty: true,
			},
			subdirectory: {
				type: DataTypes.STRING(255),
				notEmpty: false,
			},
			sourceRomId: {
				type: DataTypes.INTEGER,
				references: "Roms",
				referencesKey: "id",
			},
			targetRomId: {
				type: DataTypes.INTEGER,
				references: "Roms",
				referencesKey: "id",
			},
		});

		migration.addIndex(
			'Roms',
			[ 'incrementalId' ],
			{
				indexName: 'Roms_FetchIncremental',
			}
		);

		done();
	},

	down: function(migration, DataTypes, done) {
		migration.dropTable('Incrementals');
		migration.removeIndex('Roms', 'Roms_FetchIncremental');

		done()
	}
}
<commit_msg>Fixed migration script that creates the 'Incrementals' table.<commit_after>module.exports = {
	up: function(migration, DataTypes, done) {
		migration.createTable('Incrementals', {
			id: {
				type: DataTypes.INTEGER,
				primaryKey: true,
				autoIncrement: true,
			},
			timestamp: {
				type: DataTypes.DATE,
				notNull: true,
			},
			filename: {
				type: DataTypes.STRING(255),
				notEmpty: true,
			},
			md5sum: {
				type: DataTypes.STRING(32),
				notEmpty: true,
			},
			subdirectory: {
				type: DataTypes.STRING(255),
				notEmpty: false,
			},
			sourceRomId: {
				type: DataTypes.INTEGER,
				references: "Roms",
				referencesKey: "id",
			},
			targetRomId: {
				type: DataTypes.INTEGER,
				references: "Roms",
				referencesKey: "id",
			},
			createdAt: {
				type: DataTypes.DATE,
			},
			updatedAt: {
				type: DataTypes.DATE,
			},
		});

		done();
	},

	down: function(migration, DataTypes, done) {
		migration.dropTable('Incrementals');

		done()
	}
}
<|endoftext|>


<commit_before>var type = require('mutypes');
var mumath = require('mumath');

/** @module  intersects */
module.exports = intersect;

/** Default settings */
var defaults = {
	/** Target container to observe within */
	within: undefined,

	/** Offsets from container to provide gaps */
	offsets: 0,

	/** The amount of square to detect intersection.
	 * 0 - touches
	 * 1 - fits
	 * .5 - 50% square intersection
	 * @type {(Function|value)}
	 */
	tolerance: .5
};

/**
 * Main intersection detector.
 *
 * @param {Rectangle} a Target
 * @param {Rectangle} b Container
 *
 * @return {bool} Whether target is within the container
 */
function intersects (a, b, opts){
	//ignore definite disintersection
	if (a.right < b.left || a.left > b.right) return false;
	if (a.bottom < b.top || a.top > b.bottom) return false;

	//intersection values
	var iX = Math.min(a.right - b.left, b.right - a.left);
	var iY = Math.min(a.bottom - b.top, b.bottom - a.top);
	var iSquare = iX * iY;

	var bSquare = (b.bottom - b.top) * (b.right - b.left);
	var aSquare = (a.bottom - a.top) * (a.right - a.left);

	//measure square overlap relative to the min square
	var targetSquare = Math.min(aSquare, bSquare);

	//minimal overlap ratio
	var minRatio = opts && opts.tolerance || defaults.tolerance;

	if (iSquare / targetSquare > minRatio) {
		return true;
	}

	return false;
}<commit_msg>Fix algorithm<commit_after>var type = require('mutypes');
var mumath = require('mumath');

/** @module  intersects */
module.exports = intersects;

var min = Math.min, max = Math.max;

/** Default settings */
var defaults = {
	/** Target container to observe within */
	within: undefined,

	/** Offsets from container to provide gaps */
	offsets: 0,

	/** The amount of square to detect intersection.
	 * 0 - touches
	 * 1 - fits
	 * .5 - 50% square intersection
	 * @type {(Function|value)}
	 */
	tolerance: .5
};

/**
 * Main intersection detector.
 *
 * @param {Rectangle} a Target
 * @param {Rectangle} b Container
 *
 * @return {bool} Whether target is within the container
 */
function intersects (a, b, opts){
	//ignore definite disintersection
	if (a.right < b.left || a.left > b.right) return false;
	if (a.bottom < b.top || a.top > b.bottom) return false;

	//intersection values
	var iX = min(a.right - max(b.left, a.left), b.right - max(a.left, b.left));
	var iY = min(a.bottom - max(b.top, a.top), b.bottom - max(a.top, b.top));
	var iSquare = iX * iY;

	var bSquare = (b.bottom - b.top) * (b.right - b.left);
	var aSquare = (a.bottom - a.top) * (a.right - a.left);

	//measure square overlap relative to the min square
	var targetSquare = min(aSquare, bSquare);

	//minimal overlap ratio
	var minRatio = opts && opts.tolerance !== undefined ? opts.tolerance : defaults.tolerance;

	if (iSquare / targetSquare > minRatio) {
		return true;
	}

	return false;
}<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';

//

var templates = {
  'index-template.html': 'src/',
  'config-template.xml': '/',
  'ionic.config-template.json': '/',
  'manifest.ionic-template.json': 'src/',
  '.desktop': 'desktop/',
  'setup-win.iss': 'desktop/',
  'build-macos.sh': 'desktop/'
};
var configDir = process.argv[2] || 'copay';
var JSONheader = ' { ' + "\n" + '  "//":"Changes to this file will be overwritten",' + "\n" + '  "//":"        Modify it in the app-template directory", ' + "\n";

var MakefileHeader = "# PLEASE! Do not edit this file directly \n#       Modify it at app-template/\n";

var fs = require('fs-extra');
var path = require('path');
var shell = require('shelljs');

var configBlob = fs.readFileSync(configDir + '/appConfig.json', 'utf8');
var config = JSON.parse(configBlob, 'utf8');

/////////////////
console.log('Applying ' + config.nameCase + ' template');

Object.keys(templates).forEach(function(k) {
  var targetDir = templates[k];
  console.log(' #    ' + k + ' => ' + targetDir);

  var content = fs.readFileSync(k, 'utf8');

  if (k.indexOf('.json') > 0) {
    content = content.replace('{', JSONheader);

  } else if (k.indexOf('Makefile') >= 0) {
    content = MakefileHeader + content;
  }

  Object.keys(config).forEach(function(k) {
    if (k.indexOf('_') == 0) return;

    var r = new RegExp("\\*" + k.toUpperCase() + "\\*", "g");
    content = content.replace(r, config[k]);
  });

  var r = new RegExp("\\*[A-Z]{3,30}\\*", "g");
  var s = content.match(r);
  if (s) {
    console.log('UNKNOWN VARIABLE', s);
    process.exit(1);
  }

  if (k === 'config-template.xml') {
    k = 'config.xml';
  } else if (k === 'index-template.html') {
    k = 'index.html';
  } else if (k === 'ionic.config-template.json') {
    k = 'ionic.config.json';
  } else if (k === 'manifest.ionic-template.json') {
    k = 'manifest.json';
  }

  if (!fs.existsSync('../' + targetDir)) {
    fs.mkdirSync('../' + targetDir);
  }
  fs.writeFileSync('../' + targetDir + k, content, 'utf8');
});

/////////////////

// Get latest commit hash
var getCommitHash = function() {
  //exec git command to get the hash of the current commit
  //git rev-parse HEAD

  var hash = shell.exec('git rev-parse HEAD', {
    silent: true
  }).output.trim().substr(0, 7);
  return hash;
}

// Update appConfig.json
config['commitHash'] = getCommitHash();
console.log('Copying ' + configDir + '/appConfig.json' + ' to assets');
fs.writeJsonSync('../src/assets/appConfig.json', config, 'utf8');

////////////////
var externalServices;
try {
  var confName = configDir.toUpperCase();
  var externalServicesConf = confName + '_EXTERNAL_SERVICES_CONFIG_LOCATION';
  console.log('Looking for ' + externalServicesConf + '...');
  if (typeof process.env[externalServicesConf] !== 'undefined') {
    var location = process.env[externalServicesConf]
    if (location.charAt(0) === '~') {
      location = location.replace(/^\~/, process.env.HOME || process.env.USERPROFILE);
    }
    console.log('Found at: ' + location);
    console.log('Copying ' + location + ' to assets');
    externalServices = fs.readFileSync(location, 'utf8');
  } else {
    throw externalServicesConf + ' environment variable not set.';
  }
} catch (err) {
  console.log(err);
  externalServices = '{}';
  console.log('External services not configured');
}
fs.writeFileSync('../src/assets/externalServices.json', externalServices, 'utf8');

function copyDir(from, to, noRemove) {
  console.log('Copying dir ' + from + ' to ' + to);
  if (fs.existsSync(to) && !noRemove) fs.removeSync(to); // remove previous app directory
  if (!fs.existsSync(from)) return; // nothing to do
  fs.copySync(from, to);
}

// Push Notification
fs.copySync(configDir + '/GoogleService-Info.plist', '../GoogleService-Info.plist');
fs.copySync(configDir + '/google-services.json', '../google-services.json');

copyDir(configDir + '/img', '../src/assets/img/app');
copyDir(configDir + '/sass', '../src/theme', true);
console.log("apply.js finished. \n\n");
<commit_msg>fix(apply): shelljs API update<commit_after>#!/usr/bin/env node

'use strict';

//

var templates = {
  'index-template.html': 'src/',
  'config-template.xml': '/',
  'ionic.config-template.json': '/',
  'manifest.ionic-template.json': 'src/',
  '.desktop': 'desktop/',
  'setup-win.iss': 'desktop/',
  'build-macos.sh': 'desktop/'
};
var configDir = process.argv[2] || 'copay';
var JSONheader = ' { ' + "\n" + '  "//":"Changes to this file will be overwritten",' + "\n" + '  "//":"        Modify it in the app-template directory", ' + "\n";

var MakefileHeader = "# PLEASE! Do not edit this file directly \n#       Modify it at app-template/\n";

var fs = require('fs-extra');
var path = require('path');
var shell = require('shelljs');

var configBlob = fs.readFileSync(configDir + '/appConfig.json', 'utf8');
var config = JSON.parse(configBlob, 'utf8');

/////////////////
console.log('Applying ' + config.nameCase + ' template');

Object.keys(templates).forEach(function(k) {
  var targetDir = templates[k];
  console.log(' #    ' + k + ' => ' + targetDir);

  var content = fs.readFileSync(k, 'utf8');

  if (k.indexOf('.json') > 0) {
    content = content.replace('{', JSONheader);

  } else if (k.indexOf('Makefile') >= 0) {
    content = MakefileHeader + content;
  }

  Object.keys(config).forEach(function(k) {
    if (k.indexOf('_') == 0) return;

    var r = new RegExp("\\*" + k.toUpperCase() + "\\*", "g");
    content = content.replace(r, config[k]);
  });

  var r = new RegExp("\\*[A-Z]{3,30}\\*", "g");
  var s = content.match(r);
  if (s) {
    console.log('UNKNOWN VARIABLE', s);
    process.exit(1);
  }

  if (k === 'config-template.xml') {
    k = 'config.xml';
  } else if (k === 'index-template.html') {
    k = 'index.html';
  } else if (k === 'ionic.config-template.json') {
    k = 'ionic.config.json';
  } else if (k === 'manifest.ionic-template.json') {
    k = 'manifest.json';
  }

  if (!fs.existsSync('../' + targetDir)) {
    fs.mkdirSync('../' + targetDir);
  }
  fs.writeFileSync('../' + targetDir + k, content, 'utf8');
});

/////////////////

// Get latest commit hash
var getCommitHash = function() {
  //exec git command to get the hash of the current commit
  //git rev-parse HEAD

  var hash = shell.exec('git rev-parse HEAD', {
    silent: true
  }).stdout.trim().substr(0, 7);
  return hash;
}

// Update appConfig.json
config['commitHash'] = getCommitHash();
console.log('Copying ' + configDir + '/appConfig.json' + ' to assets');
fs.writeJsonSync('../src/assets/appConfig.json', config, 'utf8');

////////////////
var externalServices;
try {
  var confName = configDir.toUpperCase();
  var externalServicesConf = confName + '_EXTERNAL_SERVICES_CONFIG_LOCATION';
  console.log('Looking for ' + externalServicesConf + '...');
  if (typeof process.env[externalServicesConf] !== 'undefined') {
    var location = process.env[externalServicesConf]
    if (location.charAt(0) === '~') {
      location = location.replace(/^\~/, process.env.HOME || process.env.USERPROFILE);
    }
    console.log('Found at: ' + location);
    console.log('Copying ' + location + ' to assets');
    externalServices = fs.readFileSync(location, 'utf8');
  } else {
    throw externalServicesConf + ' environment variable not set.';
  }
} catch (err) {
  console.log(err);
  externalServices = '{}';
  console.log('External services not configured');
}
fs.writeFileSync('../src/assets/externalServices.json', externalServices, 'utf8');

function copyDir(from, to, noRemove) {
  console.log('Copying dir ' + from + ' to ' + to);
  if (fs.existsSync(to) && !noRemove) fs.removeSync(to); // remove previous app directory
  if (!fs.existsSync(from)) return; // nothing to do
  fs.copySync(from, to);
}

// Push Notification
fs.copySync(configDir + '/GoogleService-Info.plist', '../GoogleService-Info.plist');
fs.copySync(configDir + '/google-services.json', '../google-services.json');

copyDir(configDir + '/img', '../src/assets/img/app');
copyDir(configDir + '/sass', '../src/theme', true);
console.log("apply.js finished. \n\n");
<|endoftext|>


<commit_before>var ElasticSearchClient = require('elasticsearchclient');
var moment = require('moment');
var dateFormats = ['DD+MM+YYYY','DD+MMM+YYYY','DD MM YYYY','DD MMM YYYY'];
var airlines = {"airasia": 1, "citilink": 2, "garuda": 3, "lion": 4, "sriwijaya": 5, "xpress": 6};
var db = new ElasticSearchClient({
    host: 'folbek.me',
    port: 9200
});
var _debug = 1;
var debug = function () {
	if (_debug)
		console.log.apply(null, arguments)
}
var garuda = require('./garuda');
var lion = require('./lion');
var citilink = require('./citilink');
var express = require('./express');
var airasia = require('./airasia');
var merge = {
	garuda: garuda.mergeGaruda,
	citilink: citilink.mergeCitilink,
	lion: lion.mergeLion,
	airasia: airasia.mergeAirasia,
	xpress: express.mergeExpress,

}
var prepareOutput = {
	garuda: garuda.prepareOutputGaruda,
	citilink: citilink.prepareOutputCitilink,
	lion: lion.prepareOutputLion,
	airasia: airasia.prepareOutputAirasia,
	xpress: express.prepareOutputExpress,
}
var _next, _added;
function priceGenerator (airline) {
	_kode = airlines[airline] || 0;
	_airline = airline;
	return function (dt, json, cb) {
		this._dt = dt;
		this._realDt = dt;
		this._json = json;
		getCache(function (res) {
			// debug(res);
			mergePrice(res, cb)();
		});
	};
};
function getCache (cb) {
	if ( ['xpress', 'airasia'].indexOf(_airline) > -1 )
		return cb();
	if ( ['garuda'].indexOf(_airline) > -1) {
		var ori = _dt.ori.toLowerCase();
		var dst = _dt.dst.toLowerCase();
	} else {
		var ori = _dt.ori.toUpperCase();
		var dst = _dt.dst.toUpperCase();
	}
	var query = {"size":0, "query": {"filtered": {"filter": {"and" : [{ "term": { "origin": ori } }, { "term": { "destination": dst} }, { "term": { "airline": _airline} } ] } } }, "aggs": {"groupFlight": {"terms": {"field": "flight", }, "aggs": {"groupClass": {"terms": {"field": "class", }, "aggs": {"minPrice": {"min": {"field":"price"} } } } } } } };
	debug(JSON.stringify(query, null, 2));
	db.search('pluto', 'price', query, function (err, res) {
		// debug('res',res, _dt.ori, _dt.dst);
		cb(prepareOutput[_airline](JSON.parse(res)).data);
	});
};
function mergePrice(res, cb) {
	var _res = res;
	var _cb = cb;
	return function () {
		this.lowestPrice = 0;
		this._next = _next || [];
		this._added = _added || [_dt.ori.toLowerCase() + _dt.dst.toLowerCase()];
		var _this = this;
		merge[_airline](_res, function (res) {
			_next = _this._next || [];
			_added = _this._added || [];

			// debug(res);
			debug('lowestPrice',lowestPrice);
			var fn;
			if (lowestPrice)
				insertLowestPrice(lowestPrice);
		 	if (fn = _next.pop()){
		 		// debug('next');
		 		_json = res;
		 		fn(_cb)
		 	}
		 	else{
		 		// debug(res);
				_cb(res);
		 	}
		});
	}
}
function insertLowestPrice (price) {
	var _price = parseInt(price, 10) + _kode;
	var _date = moment(_dt.dep_date, dateFormats).unix() * 1000;
	var data = {
		date: _date,
		origin: _dt.ori,
		destination: _dt.dst,
		price: _price,
		airline: _airline
	};
	data.id = data.origin + data.destination + data.date / 1000;
	// debug('lowest',lowestPrice, JSON.stringify(data, null, 2));
	db.get(data.id, function (res) {
		var res = JSON.parse(res);
		var oldPrice = 0;
		if (res.found)
			oldPrice = res._source && res._source.price || 0;
		if ( oldPrice !== 0 && _price > oldPrice )
			return false;
		data.price = _price;
		db.index('pluto', 'calendar', data, function (err, res) {
			debug('found lower price, inserting to calendar...', res)
		})
	})
}
module.exports = priceGenerator;<commit_msg>update index<commit_after>var ElasticSearchClient = require('elasticsearchclient');
var moment = require('moment');
var dateFormats = ['DD+MM+YYYY','DD+MMM+YYYY','DD MM YYYY','DD MMM YYYY'];
var airlines = {"airasia": 1, "citilink": 2, "garuda": 3, "lion": 4, "sriwijaya": 5, "xpress": 6};
var db = new ElasticSearchClient({
    host: 'folbek.me',
    port: 9200
});
var _debug = 1;
var debug = function () {
	if (_debug)
		console.log.apply(null, arguments)
}
var garuda = require('./garuda');
var lion = require('./lion');
var citilink = require('./citilink');
var express = require('./express');
var airasia = require('./airasia');
var merge = {
	garuda: garuda.mergeGaruda,
	citilink: citilink.mergeCitilink,
	lion: lion.mergeLion,
	airasia: airasia.mergeAirasia,
	xpress: express.mergeExpress,

}
var prepareOutput = {
	garuda: garuda.prepareOutputGaruda,
	citilink: citilink.prepareOutputCitilink,
	lion: lion.prepareOutputLion,
	airasia: airasia.prepareOutputAirasia,
	xpress: express.prepareOutputExpress,
}
var _next, _added;
function priceGenerator (airline) {
	_kode = airlines[airline] || 0;
	_airline = airline;
	return function (dt, json, cb) {
		this._dt = dt;
		this._realDt = dt;
		this._json = json;
		getCache(function (res) {
			// debug(res);
			mergePrice(res, cb)();
		});
	};
};
function getCache (cb) {
	if ( ['xpress', 'airasia'].indexOf(_airline) > -1 )
		return cb();
	if ( ['garuda'].indexOf(_airline) > -1) {
		var ori = _dt.ori.toLowerCase();
		var dst = _dt.dst.toLowerCase();
	} else {
		var ori = _dt.ori.toUpperCase();
		var dst = _dt.dst.toUpperCase();
	}
	var query = {"size":0, "query": {"filtered": {"filter": {"and" : [{ "term": { "origin": ori } }, { "term": { "destination": dst} }, { "term": { "airline": _airline} } ] } } }, "aggs": {"groupFlight": {"terms": {"field": "flight", }, "aggs": {"groupClass": {"terms": {"field": "class", }, "aggs": {"minPrice": {"min": {"field":"price"} } } } } } } };
	debug(JSON.stringify(query, null, 2));
	db.search('pluto', 'price', query, function (err, res) {
		// debug('res',res, _dt.ori, _dt.dst);
		cb(prepareOutput[_airline](JSON.parse(res)).data);
	});
};
function mergePrice(res, cb) {
	var _res = res;
	var _cb = cb;
	return function () {
		this.lowestPrice = 0;
		this._next = _next || [];
		this._added = _added || [_dt.ori.toLowerCase() + _dt.dst.toLowerCase()];
		var _this = this;
		merge[_airline](_res, function (res) {
			_next = _this._next || [];
			_added = _this._added || [];

			// debug(res);
			debug('lowestPrice',lowestPrice);
			var fn;
			if (lowestPrice)
				insertLowestPrice(lowestPrice);
		 	if (fn = _next.pop()){
		 		// debug('next');
		 		_json = res;
		 		fn(_cb)
		 	}
		 	else{
		 		// debug(res);
				_cb(res);
		 	}
		});
	}
}
function insertLowestPrice (price) {
	var _price = parseInt(price, 10) + _kode;
	var _date = moment(_dt.dep_date, dateFormats).unix() * 1000;
	var data = {
		date: _date,
		origin: _dt.ori,
		destination: _dt.dst,
		price: _price,
		airline: _airline
	};
	data.id = data.origin + data.destination + data.date / 1000;
	// debug('lowest',lowestPrice, JSON.stringify(data, null, 2));
	db.get(data.id, function (err, res) {
		// debug(res)
		var res = JSON.parse(res);
		var oldPrice = 0;
		if (res.found) {
			if (res._source.airline !== _airline)
				return false;
			oldPrice = res._source && res._source.price || 0;
		}
		if ( oldPrice !== 0 && _price > oldPrice )
			return false;
		data.price = _price;
		db.index('pluto', 'calendar', data, function (err, res) {
			debug('found lower price, inserting to calendar...', res)
		})
	})
}
module.exports = priceGenerator;<|endoftext|>


<commit_before>$p.setByJson = function (json, data, $control) {
    if (json) {
        $.each(json, function () {
            $p.setByJsonElement(this, data, $control);
        });
    }
    if (json.filter(function (d) {
        return d.Method === 'Html' ||
            d.Method === 'ReplaceAll' ||
            d.Method === 'Append' ||
            d.Method === 'Prepend';
    }).length > 0) {
        $p.apply();
        $p.applyValidator();
    }
}

$p.setByJsonElement = function (jsonElement, data, $control) {
    var method = jsonElement.Method;
    var target = jsonElement.Target;
    var value = jsonElement.Value;
    switch (method) {
        case 'Html':
            $(target).html(value);
            break;
        case 'ReplaceAll':
            $(value).replaceAll(target);
            break;
        case 'Message':
            $p.setMessage(value);
            break;
        case 'Href':
            location.href = value;
            break;
        case 'PushState':
            history.pushState(target, '', value);
            break;
        case 'SetData':
            $p.setData($(target));
            break;
        case 'SetFormData':
            data[target] = value;
            break;
        case 'Append':
            $(target).append(value);
            break;
        case 'Prepend':
            $(target).prepend(value);
            break;
        case 'After':
            if ($(target).length !== 0) {
                $(target).after(value);
            } else {
                $control.after(value);
            }
            break;
        case 'Before':
            if ($(target).length !== 0) {
                $(target).before(value);
            } else {
                $control.before(value);
            }
            break;
        case 'Remove':
            $(target).remove();
            break;
        case 'Focus':
            if (target === '') {
                $('#' + data.ControlId).focus();
            } else {
                $(target).focus();
            }
            break;
        case 'SetValue':
            $p.setValue($(target), value);
            break;
        case 'ClearFormData':
            $p.clearData(target, data, value);
            break;
        case 'CloseDialog':
            $('.ui-dialog-content').dialog('close');
            break;
        case 'Trigger':
            $(target).trigger(value);
            break;
        case 'Invoke':
            $p[target]();
        case 'WindowScrollTop':
            $(window).scrollTop(value);
            break;
        case 'FocusMainForm':
            $p.focusMainForm();
            break;
        case 'Empty':
            $(target).empty();
            break;
        case 'Disabled':
            $(target).prop('disabled', value);
            break;
    }
}<commit_msg>Bug fixed: 予期せぬタイミングでスクロールがトップに戻る問題を解消。<commit_after>$p.setByJson = function (json, data, $control) {
    if (json) {
        $.each(json, function () {
            $p.setByJsonElement(this, data, $control);
        });
    }
    if (json.filter(function (d) {
        return d.Method === 'Html' ||
            d.Method === 'ReplaceAll' ||
            d.Method === 'Append' ||
            d.Method === 'Prepend';
    }).length > 0) {
        $p.apply();
        $p.applyValidator();
    }
}

$p.setByJsonElement = function (jsonElement, data, $control) {
    var method = jsonElement.Method;
    var target = jsonElement.Target;
    var value = jsonElement.Value;
    switch (method) {
        case 'Html':
            $(target).html(value);
            break;
        case 'ReplaceAll':
            $(value).replaceAll(target);
            break;
        case 'Message':
            $p.setMessage(value);
            break;
        case 'Href':
            location.href = value;
            break;
        case 'PushState':
            history.pushState(target, '', value);
            break;
        case 'SetData':
            $p.setData($(target));
            break;
        case 'SetFormData':
            data[target] = value;
            break;
        case 'Append':
            $(target).append(value);
            break;
        case 'Prepend':
            $(target).prepend(value);
            break;
        case 'After':
            if ($(target).length !== 0) {
                $(target).after(value);
            } else {
                $control.after(value);
            }
            break;
        case 'Before':
            if ($(target).length !== 0) {
                $(target).before(value);
            } else {
                $control.before(value);
            }
            break;
        case 'Remove':
            $(target).remove();
            break;
        case 'Focus':
            if (target === '') {
                $('#' + data.ControlId).focus();
            } else {
                $(target).focus();
            }
            break;
        case 'SetValue':
            $p.setValue($(target), value);
            break;
        case 'ClearFormData':
            $p.clearData(target, data, value);
            break;
        case 'CloseDialog':
            $('.ui-dialog-content').dialog('close');
            break;
        case 'Trigger':
            $(target).trigger(value);
            break;
        case 'Invoke':
            $p[target]();
            break;
        case 'WindowScrollTop':
            $(window).scrollTop(value);
            break;
        case 'FocusMainForm':
            $p.focusMainForm();
            break;
        case 'Empty':
            $(target).empty();
            break;
        case 'Disabled':
            $(target).prop('disabled', value);
            break;
    }
}<|endoftext|>


<commit_before>var {EventEmitter} = require('fbemitter');
export var emitter = new EventEmitter();

class ImmutableQuery {
  constructor() {
    this.shouldArray = [];
    this.filterArray = [];
    this.config = [];
  }
  setConfig(config) {
    this.config = config.appbase;
  }
  addShouldClause(key, value) {
    this.shouldArray.push(this.getKeyValueObject(key, value));
    return this.buildQuery();
  }
  removeShouldClause(key, value) {
    var index = this.getShouldArrayIndex(key, value);
    this.shouldArray.splice(index, 1);
    return this.buildQuery();
  }
  buildQuery(geo) {
    this.query = {
      type: this.config.type,
      body: {
        "size": 100,
        "query": {
          "bool": {
            "must": this.shouldArray,
            "filter": this.filterArray
          }
        }
      }
    };
    if (!geo)
      emitter.emit('change', this.query);
    return this.query;
  }
  getKeyValueObject(key, value) {
    var term = JSON.parse(`{"${key}":` + JSON.stringify(value) + '}');
    return { term };
  }
  getShouldArrayIndex(key, value) {
    var array = this.shouldArray
    var encode64 = btoa(JSON.stringify(this.getKeyValueObject(key, value)));
    for (var i = 0; i < array.length; i++) {
      if (btoa(JSON.stringify(array[i])) === encode64) {
        return i;
      }
    }
    return -1;
  }
}

export const queryObject = new ImmutableQuery();<commit_msg>Implement geo filter<commit_after>var {EventEmitter} = require('fbemitter');
export var emitter = new EventEmitter();

class ImmutableQuery {
  constructor() {
    this.shouldArray = [];
    this.filterArray = [];
    this.config = [];
  }
  setConfig(config) {
    this.config = config.appbase;
  }
  addShouldClause(key, value) {
    this.shouldArray.push(this.getKeyValueObject(key, value));
    return this.buildQuery();
  }
  updateGeoFilter(key, boundingBoxCoordinates) {
    var geoObject = JSON.parse(`{"${key}":` + JSON.stringify(boundingBoxCoordinates) + '}');
    this.filterArray[0] = { geo_bounding_box: geoObject };
    return this.buildQuery(true);
  }
  removeShouldClause(key, value) {
    var index = this.getShouldArrayIndex(key, value);
    this.shouldArray.splice(index, 1);
    return this.buildQuery();
  }
  buildQuery(geo) {
    this.query = {
      type: this.config.type,
      body: {
        "size": 100,
        "query": {
          "bool": {
            "must": this.shouldArray,
            "filter": this.filterArray
          }
        }
      }
    };
    if (!geo)
      emitter.emit('change', this.query);
    return this.query;
  }
  getKeyValueObject(key, value) {
    var term = JSON.parse(`{"${key}":` + JSON.stringify(value) + '}');
    return { term };
  }
  getShouldArrayIndex(key, value) {
    var array = this.shouldArray
    var encode64 = btoa(JSON.stringify(this.getKeyValueObject(key, value)));
    for (var i = 0; i < array.length; i++) {
      if (btoa(JSON.stringify(array[i])) === encode64) {
        return i;
      }
    }
    return -1;
  }
}

export const queryObject = new ImmutableQuery();<|endoftext|>