<commit_before>const fs = require('fs')
const path = require('path')
const process = require('process')
const os = require('os')

const makeDir = require('make-dir')
const inquirer = require('inquirer')
const _ = require('lodash/fp')

const { utils: coinUtils } = require('lamassu-coins')
const options = require('../options')

const common = require('./common')
const doVolume = require('./do-volume')

const cryptos = coinUtils.cryptoCurrencies()

const logger = common.logger

const PLUGINS = {
  BTC: require('./bitcoin.js'),
  BCH: require('./bitcoincash.js'),
  DASH: require('./dash.js'),
  ETH: require('./ethereum.js'),
  LTC: require('./litecoin.js'),
  XMR: require('./monero.js'),
  ZEC: require('./zcash.js')
}

module.exports = {run}

function installedVolumeFilePath (crypto) {
  return path.resolve(coinUtils.cryptoDir(crypto, options.blockchainDir), '.installed')
}

function isInstalledVolume (crypto) {
  return fs.existsSync(installedVolumeFilePath(crypto))
}

function isInstalledSoftware (crypto) {
  return common.isInstalledSoftware(crypto)
}

function processCryptos (codes) {
  if (_.isEmpty(codes)) {
    logger.info('No cryptos selected. Exiting.')
    process.exit(0)
  }

  logger.info('Thanks! Installing: %s. Will take a while...', _.join(', ', codes))

  const goodVolume = doVolume.prepareVolume()

  if (!goodVolume) {
    logger.error('There was an error preparing the disk volume. Exiting.')
    process.exit(1)
  }

  const selectedCryptos = _.map(code => _.find(['code', code], cryptos), codes)
  _.forEach(setupCrypto, selectedCryptos)
  common.es('sudo supervisorctl reread')
  common.es('sudo supervisorctl update')

  const blockchainDir = options.blockchainDir
  const backupDir = path.resolve(os.homedir(), 'backups')
  const rsyncCmd = `( \
    (crontab -l 2>/dev/null || echo -n "") | grep -v "@daily rsync ".*"wallet.dat"; \
    echo "@daily rsync -r --prune-empty-dirs --include='*/' \
                        --include='wallet.dat' \
                        --exclude='*' ${blockchainDir} ${backupDir} > /dev/null" \
  ) | crontab -`
  common.es(rsyncCmd)

  _.forEach(c => {
    updateCrypto(c)
    common.es(`sudo supervisorctl start ${c.code}`)
  }, selectedCryptos)

  logger.info('Installation complete.')
}

function setupCrypto (crypto) {
  logger.info(`Installing ${crypto.display}...`)
  const cryptoDir = coinUtils.cryptoDir(crypto, options.blockchainDir)
  makeDir.sync(cryptoDir)
  const cryptoPlugin = plugin(crypto)
  const oldDir = process.cwd()
  const tmpDir = '/tmp/blockchain-install'

  makeDir.sync(tmpDir)
  process.chdir(tmpDir)
  common.es('rm -rf *')
  common.fetchAndInstall(crypto)

  cryptoPlugin.setup(cryptoDir)

  common.writeFile(installedVolumeFilePath(crypto), '')
  process.chdir(oldDir)
}

function updateCrypto (crypto) {
  if (!common.isUpdateDependent(crypto.cryptoCode)) return
  const cryptoPlugin = plugin(crypto)
  const status = common.es(`sudo supervisorctl status ${crypto.code} | awk '{ print $2 }'`).trim()
  const isCurrentlyRunning = status === 'RUNNING'
  cryptoPlugin.updateCore(common.getBinaries(crypto.cryptoCode), isCurrentlyRunning)
}

function plugin (crypto) {
  const plugin = PLUGINS[crypto.cryptoCode]
  if (!plugin) throw new Error(`No such plugin: ${crypto.cryptoCode}`)
  return plugin
}

function run () {  
  const choices = _.map(c => {
    const checked = isInstalledSoftware(c) && isInstalledVolume(c)
    return {
      name: c.display,
      value: c.code,
      checked,
      disabled: checked && 'Installed'
    }
  }, cryptos)

  const questions = []

  questions.push({
    type: 'checkbox',
    name: 'crypto',
    message: 'Which cryptocurrencies would you like to install?',
    choices
  })

  inquirer.prompt(questions)
    .then(answers => processCryptos(answers.crypto))
}<commit_msg>refactor: filter Tether/USDT from install candidates<commit_after>const fs = require('fs')
const path = require('path')
const process = require('process')
const os = require('os')

const makeDir = require('make-dir')
const inquirer = require('inquirer')
const _ = require('lodash/fp')

const { utils: coinUtils } = require('lamassu-coins')
const options = require('../options')

const common = require('./common')
const doVolume = require('./do-volume')

const cryptos = coinUtils.cryptoCurrencies()

const logger = common.logger

const PLUGINS = {
  BTC: require('./bitcoin.js'),
  BCH: require('./bitcoincash.js'),
  DASH: require('./dash.js'),
  ETH: require('./ethereum.js'),
  LTC: require('./litecoin.js'),
  XMR: require('./monero.js'),
  ZEC: require('./zcash.js')
}

module.exports = {run}

function installedVolumeFilePath (crypto) {
  return path.resolve(coinUtils.cryptoDir(crypto, options.blockchainDir), '.installed')
}

function isInstalledVolume (crypto) {
  return fs.existsSync(installedVolumeFilePath(crypto))
}

function isInstalledSoftware (crypto) {
  return common.isInstalledSoftware(crypto)
}

function processCryptos (codes) {
  if (_.isEmpty(codes)) {
    logger.info('No cryptos selected. Exiting.')
    process.exit(0)
  }

  logger.info('Thanks! Installing: %s. Will take a while...', _.join(', ', codes))

  const goodVolume = doVolume.prepareVolume()

  if (!goodVolume) {
    logger.error('There was an error preparing the disk volume. Exiting.')
    process.exit(1)
  }

  const selectedCryptos = _.map(code => _.find(['code', code], cryptos), codes)
  _.forEach(setupCrypto, selectedCryptos)
  common.es('sudo supervisorctl reread')
  common.es('sudo supervisorctl update')

  const blockchainDir = options.blockchainDir
  const backupDir = path.resolve(os.homedir(), 'backups')
  const rsyncCmd = `( \
    (crontab -l 2>/dev/null || echo -n "") | grep -v "@daily rsync ".*"wallet.dat"; \
    echo "@daily rsync -r --prune-empty-dirs --include='*/' \
                        --include='wallet.dat' \
                        --exclude='*' ${blockchainDir} ${backupDir} > /dev/null" \
  ) | crontab -`
  common.es(rsyncCmd)

  _.forEach(c => {
    updateCrypto(c)
    common.es(`sudo supervisorctl start ${c.code}`)
  }, selectedCryptos)

  logger.info('Installation complete.')
}

function setupCrypto (crypto) {
  logger.info(`Installing ${crypto.display}...`)
  const cryptoDir = coinUtils.cryptoDir(crypto, options.blockchainDir)
  makeDir.sync(cryptoDir)
  const cryptoPlugin = plugin(crypto)
  const oldDir = process.cwd()
  const tmpDir = '/tmp/blockchain-install'

  makeDir.sync(tmpDir)
  process.chdir(tmpDir)
  common.es('rm -rf *')
  common.fetchAndInstall(crypto)

  cryptoPlugin.setup(cryptoDir)

  common.writeFile(installedVolumeFilePath(crypto), '')
  process.chdir(oldDir)
}

function updateCrypto (crypto) {
  if (!common.isUpdateDependent(crypto.cryptoCode)) return
  const cryptoPlugin = plugin(crypto)
  const status = common.es(`sudo supervisorctl status ${crypto.code} | awk '{ print $2 }'`).trim()
  const isCurrentlyRunning = status === 'RUNNING'
  cryptoPlugin.updateCore(common.getBinaries(crypto.cryptoCode), isCurrentlyRunning)
}

function plugin (crypto) {
  const plugin = PLUGINS[crypto.cryptoCode]
  if (!plugin) throw new Error(`No such plugin: ${crypto.cryptoCode}`)
  return plugin
}

function run () {  
  const choices = _.flow([
    _.filter(c => c.type !== 'erc-20'),
    _.map(c => {
      const checked = isInstalledSoftware(c) && isInstalledVolume(c)
      return {
        name: c.display,
        value: c.code,
        checked,
        disabled: checked && 'Installed'
      }
    }),
  ])(cryptos)

  const questions = []

  questions.push({
    type: 'checkbox',
    name: 'crypto',
    message: 'Which cryptocurrencies would you like to install?',
    choices
  })

  inquirer.prompt(questions)
    .then(answers => processCryptos(answers.crypto))
}
{'fraction_non_alphanumeric': 0.15251612903225806, 'fraction_numerical': 0.0012903225806451613, 'mean_word_length': 3.8902208201892745, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5686648', 'n_tokens_mistral': 2543, 'n_tokens_neox': 2435, 'n_words': 549}