1
1
mirror of https://github.com/leon-ai/leon.git synced 2024-12-24 17:23:23 +03:00
leon/scripts/check.js

242 lines
9.2 KiB
JavaScript
Raw Normal View History

2019-02-10 15:26:50 +03:00
import dotenv from 'dotenv'
import fs from 'fs'
import { command } from 'execa'
2019-02-10 15:26:50 +03:00
import semver from 'semver'
import { version } from '@@/package.json'
2019-02-10 15:26:50 +03:00
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'
2019-06-08 06:33:22 +03:00
const pythonMinRequiredVersion = '3'
2019-02-10 15:26:50 +03:00
const flitePath = 'bin/flite/flite'
2022-01-24 10:20:04 +03:00
const coquiLanguageModelPath = 'bin/coqui/huge-vocabulary.scorer'
const amazonPath = 'core/config/voice/amazon.json'
const googleCloudPath = 'core/config/voice/google-cloud.json'
const watsonSttPath = 'core/config/voice/watson-stt.json'
const watsonTtsPath = 'core/config/voice/watson-tts.json'
2022-07-19 16:57:00 +03:00
const globalResolversNlpModelPath = 'core/data/models/leon-global-resolvers-model.nlp'
const skillsResolversNlpModelPath = 'core/data/models/leon-skills-resolvers-model.nlp'
const mainNlpModelPath = 'core/data/models/leon-main-model.nlp'
2019-02-10 15:26:50 +03:00
const report = {
can_run: { title: 'Run', type: 'error', v: true },
can_run_skill: { title: 'Run skills', type: 'error', v: true },
2019-02-10 15:26:50 +03:00
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')
// Leon version checking
log.info('Leon version')
log.success(`${version}\n`);
2019-02-10 15:26:50 +03:00
// Environment checking
2021-03-15 20:39:52 +03:00
(await Promise.all([
command('node --version', { shell: true }),
command('npm --version', { shell: true }),
command('pipenv --version', { shell: true })
2019-02-10 15:26:50 +03:00
])).forEach((p) => {
log.info(p.command)
2019-02-10 15:26:50 +03:00
2021-03-15 20:39:52 +03:00
if (p.command.indexOf('node --version') !== -1
&& !semver.satisfies(semver.clean(p.stdout), `>=${nodeMinRequiredVersion}`)) {
2019-02-10 15:26:50 +03:00
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`)
2021-03-15 20:39:52 +03:00
} else if (p.command.indexOf('npm --version') !== -1
&& !semver.satisfies(semver.clean(p.stdout), `>=${npmMinRequiredVersion}`)) {
2019-02-10 15:26:50 +03:00
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`)
}
2021-03-15 20:39:52 +03:00
});
2019-02-10 15:26:50 +03:00
2021-03-15 20:39:52 +03:00
(await Promise.all([
command('pipenv --where', { shell: true }),
command('pipenv run python --version', { shell: true })
2019-02-10 15:26:50 +03:00
])).forEach((p) => {
log.info(p.command)
2019-02-10 15:26:50 +03:00
2021-03-15 20:39:52 +03:00
if (p.command.indexOf('pipenv run python --version') !== -1
&& !semver.satisfies(p.stdout.split(' ')[1], `>=${pythonMinRequiredVersion}`)) {
2019-02-10 15:26:50 +03:00
Object.keys(report).forEach((item) => { if (report[item].type === 'error') report[item].v = false })
2019-06-08 06:33:22 +03:00
log.error(`${p.stdout}\nThe Python version must be >=${pythonMinRequiredVersion}. Please install it: https://www.python.org/downloads\n`)
2019-02-10 15:26:50 +03:00
} else {
log.success(`${p.stdout}\n`)
}
})
// Skill execution checking
2019-02-10 15:26:50 +03:00
try {
2022-02-10 16:47:43 +03:00
const p = await command('pipenv run python bridges/python/main.py scripts/assets/intent-object.json', { shell: true })
log.info(p.command)
2019-02-10 15:26:50 +03:00
log.success(`${p.stdout}\n`)
} catch (e) {
log.info(e.command)
report.can_run_skill.v = false
2019-02-10 15:26:50 +03:00
log.error(`${e}\n`)
}
2022-07-19 16:57:00 +03:00
// Global resolvers NLP model checking
2019-02-10 15:26:50 +03:00
2022-07-19 16:57:00 +03:00
log.info('Global resolvers NLP model state')
if (!fs.existsSync(globalResolversNlpModelPath)
|| !Object.keys(fs.readFileSync(globalResolversNlpModelPath)).length) {
2019-02-10 15:26:50 +03:00
report.can_text.v = false
Object.keys(report).forEach((item) => { if (item.indexOf('stt') !== -1 || item.indexOf('tts') !== -1) report[item].v = false })
2022-07-19 16:57:00 +03:00
log.error('Global resolvers NLP model not found or broken. Try to generate a new one: "npm run train"\n')
} else {
log.success('Found and valid\n')
}
// Skills resolvers NLP model checking
log.info('Skills resolvers NLP model state')
if (!fs.existsSync(skillsResolversNlpModelPath)
|| !Object.keys(fs.readFileSync(skillsResolversNlpModelPath)).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('Skills resolvers NLP model not found or broken. Try to generate a new one: "npm run train"\n')
} else {
log.success('Found and valid\n')
}
// Main NLP model checking
log.info('Main NLP model state')
if (!fs.existsSync(mainNlpModelPath)
|| !Object.keys(fs.readFileSync(mainNlpModelPath)).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('Main NLP model not found or broken. Try to generate a new one: "npm run train"\n')
2019-02-10 15:26:50 +03:00
} else {
log.success('Found and valid\n')
}
// TTS checking
log.info('Amazon Polly TTS')
try {
const json = JSON.parse(fs.readFileSync(amazonPath))
if (json.credentials.accessKeyId === '' || json.credentials.secretAccessKey === '') {
2019-02-10 15:26:50 +03:00
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')
2022-01-24 10:20:04 +03:00
if (!fs.existsSync(coquiLanguageModelPath)) {
2019-02-10 15:26:50 +03:00
report.can_offline_stt.v = false
2022-01-24 10:20:04 +03:00
log.warning(`Cannot find ${coquiLanguageModelPath}. You can setup the offline STT by running: "npm run setup:offline-stt"`)
2019-02-10 15:26:50 +03:00
} else {
2022-01-24 10:20:04 +03:00
log.success(`Found Coqui language model at ${coquiLanguageModelPath}`)
2019-02-10 15:26:50 +03:00
}
// 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_skill.v && report.can_text.v) {
2019-02-10 15:26:50 +03:00
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()
}
})