mirror of
https://github.com/leon-ai/leon.git
synced 2024-12-19 14:52:21 +03:00
209 lines
7.6 KiB
JavaScript
209 lines
7.6 KiB
JavaScript
import dotenv from 'dotenv'
|
|
import fs from 'fs'
|
|
import { shell } from 'execa'
|
|
import semver from 'semver'
|
|
|
|
import log from '@/helpers/log'
|
|
|
|
dotenv.config()
|
|
|
|
/**
|
|
* Checking script
|
|
* Help to figure out what is installed or not
|
|
*/
|
|
export default () => new Promise(async (resolve, reject) => {
|
|
try {
|
|
const nodeMinRequiredVersion = '10'
|
|
const npmMinRequiredVersion = '5'
|
|
const pythonRequiredVersion = '3.6'
|
|
const flitePath = 'bin/flite/flite'
|
|
const deepSpeechPath = 'bin/deepspeech/lm.binary'
|
|
const amazonPath = 'server/src/config/voice/amazon.json'
|
|
const googleCloudPath = 'server/src/config/voice/google-cloud.json'
|
|
const watsonSttPath = 'server/src/config/voice/watson-stt.json'
|
|
const watsonTtsPath = 'server/src/config/voice/watson-tts.json'
|
|
const classifierPath = 'server/src/data/expressions/classifier.json'
|
|
const report = {
|
|
can_run: { title: 'Run', type: 'error', v: true },
|
|
can_run_module: { title: 'Run modules', type: 'error', v: true },
|
|
can_text: { title: 'Reply you by texting', type: 'error', v: true },
|
|
can_amazon_polly_tts: { title: 'Amazon Polly text-to-speech', type: 'warning', v: true },
|
|
can_google_cloud_tts: { title: 'Google Cloud text-to-speech', type: 'warning', v: true },
|
|
can_watson_tts: { title: 'Watson text-to-speech', type: 'warning', v: true },
|
|
can_offline_tts: { title: 'Offline text-to-speech', type: 'warning', v: true },
|
|
can_google_cloud_stt: { title: 'Google Cloud speech-to-text', type: 'warning', v: true },
|
|
can_watson_stt: { title: 'Watson speech-to-text', type: 'warning', v: true },
|
|
can_offline_stt: { title: 'Offline speech-to-text', type: 'warning', v: true }
|
|
}
|
|
|
|
log.title('Checking');
|
|
|
|
// Environment checking
|
|
|
|
(await Promise.all([
|
|
shell('node --version'),
|
|
shell('npm --version'),
|
|
shell('pipenv --version')
|
|
])).forEach((p) => {
|
|
log.info(p.cmd)
|
|
|
|
if (p.cmd.indexOf('node --version') !== -1 &&
|
|
!semver.satisfies(semver.clean(p.stdout), `>=${nodeMinRequiredVersion}`)) {
|
|
Object.keys(report).forEach((item) => { if (report[item].type === 'error') report[item].v = false })
|
|
log.error(`${p.stdout}\nThe Node.js version must be >=${nodeMinRequiredVersion}. Please install it: https://nodejs.org (or use nvm)\n`)
|
|
} else if (p.cmd.indexOf('npm --version') !== -1 &&
|
|
!semver.satisfies(semver.clean(p.stdout), `>=${npmMinRequiredVersion}`)) {
|
|
Object.keys(report).forEach((item) => { if (report[item].type === 'error') report[item].v = false })
|
|
log.error(`${p.stdout}\nThe npm version must be >=${npmMinRequiredVersion}. Please install it: https://www.npmjs.com/get-npm (or use nvm)\n`)
|
|
} else {
|
|
log.success(`${p.stdout}\n`)
|
|
}
|
|
});
|
|
|
|
(await Promise.all([
|
|
shell('pipenv --where'),
|
|
shell('pipenv run python --version')
|
|
])).forEach((p) => {
|
|
log.info(p.cmd)
|
|
|
|
if (p.cmd.indexOf('pipenv run python --version') !== -1 &&
|
|
!semver.satisfies(p.stdout.split(' ')[1], pythonRequiredVersion)) {
|
|
Object.keys(report).forEach((item) => { if (report[item].type === 'error') report[item].v = false })
|
|
log.error(`${p.stdout}\nThe Python version must be ${pythonRequiredVersion}.x. Please install it: https://www.python.org/downloads\n`)
|
|
} else {
|
|
log.success(`${p.stdout}\n`)
|
|
}
|
|
})
|
|
|
|
// Module execution checking
|
|
|
|
try {
|
|
const p = await shell('pipenv run python bridges/python/main.py scripts/assets/query-object.json')
|
|
log.info(p.cmd)
|
|
log.success(`${p.stdout}\n`)
|
|
} catch (e) {
|
|
log.info(e.cmd)
|
|
report.can_run_module.v = false
|
|
log.error(`${e}\n`)
|
|
}
|
|
|
|
// Classifier checking
|
|
|
|
log.info('Classifier state')
|
|
if (!fs.existsSync(classifierPath) || !Object.keys(fs.readFileSync(classifierPath)).length) {
|
|
report.can_text.v = false
|
|
Object.keys(report).forEach((item) => { if (item.indexOf('stt') !== -1 || item.indexOf('tts') !== -1) report[item].v = false })
|
|
log.error('Classifier not found or broken. Try to generate a new one: "npm run train expressions"\n')
|
|
} else {
|
|
log.success('Found and valid\n')
|
|
}
|
|
|
|
// TTS checking
|
|
|
|
log.info('Amazon Polly TTS')
|
|
try {
|
|
const json = JSON.parse(fs.readFileSync(amazonPath))
|
|
if (json.accessKeyId === '' || json.secretAccessKey === '') {
|
|
report.can_amazon_polly_tts.v = false
|
|
log.warning('Amazon Polly TTS is not yet configured\n')
|
|
} else {
|
|
log.success('Configured\n')
|
|
}
|
|
} catch (e) {
|
|
report.can_amazon_polly_tts.v = false
|
|
log.warning(`Amazon Polly TTS is not yet configured: ${e}\n`)
|
|
}
|
|
|
|
log.info('Google Cloud TTS/STT')
|
|
try {
|
|
const json = JSON.parse(fs.readFileSync(googleCloudPath))
|
|
const results = []
|
|
Object.keys(json).forEach((item) => { if (json[item] === '') results.push(false) })
|
|
if (results.includes(false)) {
|
|
report.can_google_cloud_tts.v = false
|
|
report.can_google_cloud_stt.v = false
|
|
log.warning('Google Cloud TTS/STT is not yet configured\n')
|
|
} else {
|
|
log.success('Configured\n')
|
|
}
|
|
} catch (e) {
|
|
report.can_google_cloud_tts.v = false
|
|
report.can_google_cloud_stt.v = false
|
|
log.warning(`Google Cloud TTS/STT is not yet configured: ${e}\n`)
|
|
}
|
|
|
|
log.info('Watson TTS')
|
|
try {
|
|
const json = JSON.parse(fs.readFileSync(watsonTtsPath))
|
|
const results = []
|
|
Object.keys(json).forEach((item) => { if (json[item] === '') results.push(false) })
|
|
if (results.includes(false)) {
|
|
report.can_watson_tts.v = false
|
|
log.warning('Watson TTS is not yet configured\n')
|
|
} else {
|
|
log.success('Configured\n')
|
|
}
|
|
} catch (e) {
|
|
report.can_watson_tts.v = false
|
|
log.warning(`Watson TTS is not yet configured: ${e}\n`)
|
|
}
|
|
|
|
log.info('Offline TTS')
|
|
if (!fs.existsSync(flitePath)) {
|
|
report.can_offline_tts.v = false
|
|
log.warning(`Cannot find ${flitePath}. You can setup the offline TTS by running: "npm run setup:offline-tts"\n`)
|
|
} else {
|
|
log.success(`Found Flite at ${flitePath}\n`)
|
|
}
|
|
|
|
log.info('Watson STT')
|
|
try {
|
|
const json = JSON.parse(fs.readFileSync(watsonSttPath))
|
|
const results = []
|
|
Object.keys(json).forEach((item) => { if (json[item] === '') results.push(false) })
|
|
if (results.includes(false)) {
|
|
report.can_watson_stt.v = false
|
|
log.warning('Watson STT is not yet configured\n')
|
|
} else {
|
|
log.success('Configured\n')
|
|
}
|
|
} catch (e) {
|
|
report.can_watson_stt.v = false
|
|
log.warning(`Watson STT is not yet configured: ${e}`)
|
|
}
|
|
|
|
log.info('Offline STT')
|
|
if (!fs.existsSync(deepSpeechPath)) {
|
|
report.can_offline_stt.v = false
|
|
log.warning(`Cannot find ${deepSpeechPath}. You can setup the offline STT by running: "npm run setup:offline-stt"`)
|
|
} else {
|
|
log.success(`Found DeepSpeech language model at ${deepSpeechPath}`)
|
|
}
|
|
|
|
// Report
|
|
log.title('Report')
|
|
|
|
log.info('Here is the diagnosis about your current setup')
|
|
Object.keys(report).forEach((item) => {
|
|
if (report[item].v === true) {
|
|
log.success(report[item].title)
|
|
} else {
|
|
log[report[item].type](report[item].title)
|
|
}
|
|
})
|
|
|
|
log.default('')
|
|
if (report.can_run.v && report.can_run_module.v && report.can_text.v) {
|
|
log.success('Hooray! Leon can run correctly')
|
|
log.info('If you have some yellow warnings, it is all good. It means some entities are not yet configured')
|
|
} else {
|
|
log.error('Please fix the errors above')
|
|
}
|
|
|
|
resolve()
|
|
} catch (e) {
|
|
log.error(e)
|
|
reject()
|
|
}
|
|
})
|