|
1 | 1 | import {CLIError, Command, flags} from '@microsoft/bf-cli-command' |
2 | 2 | const fs = require('fs-extra') |
3 | 3 | const path = require('path') |
4 | | -const helpers = require('./../../../parser/lufile/helpers') |
| 4 | +const fileHelper = require('./../../utils/filehelper') |
| 5 | +const exception = require('./../../../parser/lufile/classes/exception') |
5 | 6 | const luTranslator = require('./../../../parser/translator/lutranslate') |
6 | 7 | const luisConverter = require('./../../../parser/converters/luistoluconverter') |
7 | | -const luConverter = require('./../../../parser/converters/lutoluisconverter') |
| 8 | +const luConverter = require('./../../../parser/lufile/parseFileContents') |
8 | 9 |
|
9 | 10 | export default class LuisTranslate extends Command { |
10 | 11 | static description = ' Translate given LUIS application JSON model or lu file(s)' |
11 | 12 |
|
12 | 13 | static flags: flags.Input<any> = { |
13 | 14 | in: flags.string({description: 'Source .lu file(s) or LUIS application JSON model', required: true}), |
14 | 15 | recurse: flags.boolean({description: 'Indicates if sub-folders need to be considered to file .lu file(s)'}), |
15 | | - out: flags.string({description: 'Output file or folder name. If not specified stdout will be used as output'}), |
| 16 | + out: flags.string({description: 'Output folder name. If not specified stdout will be used as output'}), |
16 | 17 | srclang: flags.string({description: 'Source lang code. Auto detect if missing.'}), |
17 | 18 | tgtlang: flags.string({description: 'Comma separated list of target languages.', required: true}), |
18 | 19 | translatekey: flags.string({description: 'Machine translation endpoint key.', required: true}), |
19 | 20 | translate_comments: flags.string({description: 'When set, machine translate comments found in .lu or .qna file'}), |
20 | 21 | translate_link_text: flags.string({description: 'When set, machine translate link description in .lu or .qna file'}), |
21 | 22 | } |
22 | 23 |
|
23 | | - inputStat: any |
24 | | - |
| 24 | + /* tslint:disable:forin no-for-in*/ |
25 | 25 | async run() { |
26 | 26 | try { |
27 | 27 | const {flags} = this.parse(LuisTranslate) |
28 | | - this.inputStat = await fs.stat(flags.in) |
| 28 | + let inputStat = await fs.stat(flags.in) |
29 | 29 | let outputStat = flags.out ? await fs.stat(flags.out) : undefined |
30 | 30 |
|
31 | | - if (!this.inputStat.isFile() && outputStat && outputStat.isFile()) { |
32 | | - throw new CLIError('Specified output cannot be applied to input') |
| 31 | + if (outputStat && outputStat.isFile()) { |
| 32 | + throw new CLIError('Output can only be writen to a folder') |
33 | 33 | } |
34 | 34 |
|
35 | | - let isLu = !this.inputStat.isFile() ? true : path.extname(flags.in) === '.lu' |
| 35 | + let isLu = !inputStat.isFile() ? true : path.extname(flags.in) === '.lu' |
36 | 36 | let result: any |
37 | | - let luFiles: any |
38 | 37 | if (isLu) { |
39 | | - luFiles = await this.getLuFiles(flags.in, flags.recurse) |
| 38 | + let luFiles = await fileHelper.getLuFiles(flags.in, flags.recurse) |
40 | 39 | result = await luTranslator.translateLuFile(luFiles, flags.translatekey, flags.tgtlang, flags.srclang, flags.translate_comments, flags.translate_link_text) |
41 | 40 | } else { |
42 | | - result = await luisConverter.parseLuisFileToLu(flags.in, false) |
43 | | - result = await luTranslator.translateLuObject(result, flags.translatekey, flags.tgtlang, flags.srclang, flags.translate_comments, flags.translate_link_text) |
44 | | - let tempFile = path.join(__dirname, 'tempfile') |
45 | | - await fs.writeFile(tempFile, result['luTranslation'][flags.tgtlang]) |
46 | | - result = await luConverter.parseLuToLuis([tempFile], false, undefined) |
47 | | - await fs.remove(tempFile) |
| 41 | + let translation = await luisConverter.parseLuisFileToLu(flags.in, false) |
| 42 | + translation = await luTranslator.translateLuObj(result, flags.translatekey, flags.tgtlang, flags.srclang, flags.translate_comments, flags.translate_link_text) |
| 43 | + result = {} |
| 44 | + Object.keys(translation).forEach(async idx => { |
| 45 | + result[flags.in][idx] = await luConverter.parseFile(translation[idx][0], false, undefined) |
| 46 | + }) |
48 | 47 | } |
49 | 48 |
|
50 | 49 | if (flags.out) { |
51 | | - let languages = flags.tgtlang.split(',') |
52 | | - await this.writeOutput(result, luFiles, isLu, languages, flags.out) |
| 50 | + await this.writeOutput(result, flags.out) |
53 | 51 | } else { |
54 | 52 | this.log(result) |
55 | 53 | } |
56 | 54 |
|
57 | 55 | } catch (err) { |
| 56 | + if (err instanceof exception) { |
| 57 | + throw new CLIError(err.text) |
| 58 | + } |
58 | 59 | throw err |
59 | 60 | } |
60 | 61 | } |
61 | 62 |
|
62 | | - private async getLuFiles(input: string | undefined, recurse = false): Promise<Array<any>> { |
63 | | - let filesToParse = [] |
64 | | - |
65 | | - if (this.inputStat.isFile()) { |
66 | | - filesToParse.push(input) |
67 | | - return filesToParse |
68 | | - } |
69 | | - |
70 | | - if (!this.inputStat.isDirectory()) { |
71 | | - throw new CLIError('Sorry, ' + input + ' is not a folder or does not exist') |
72 | | - } |
73 | | - |
74 | | - filesToParse = helpers.findLUFiles(input, recurse) |
75 | | - |
76 | | - if (filesToParse.length === 0) { |
77 | | - throw new CLIError('Sorry, no .lu files found in the specified folder.') |
78 | | - } |
79 | | - return filesToParse |
80 | | - } |
81 | | - |
82 | | - private async writeOutput(translatedObject: any, files: Array<string>, isLu: boolean, languages: Array<string>, out: string) { |
| 63 | + private async writeOutput(translatedObject: any, out: string) { |
83 | 64 | let filePath = '' |
84 | 65 | try { |
85 | | - if (isLu) { |
86 | | - let fileIndex = 0 |
87 | | - while (files.length > fileIndex) { |
88 | | - let file = files[fileIndex++] + '' |
89 | | - let lngIndex = 0 |
90 | | - while (languages.length > lngIndex) { |
91 | | - let lg = languages[lngIndex++] + '' |
92 | | - filePath = await this.generateNewFilePath(path.basename(file), lg, out) |
93 | | - await fs.writeFile(filePath, translatedObject[path.basename(file)][lg], 'utf-8') |
94 | | - } |
| 66 | + for (let file in translatedObject) { |
| 67 | + for (let lng in translatedObject[file]) { |
| 68 | + filePath = await fileHelper.generateNewTranslatedFilePath(file, lng, out) |
| 69 | + await fs.writeFile(filePath, translatedObject[path.basename(file)][lng], 'utf-8') |
95 | 70 | } |
96 | | - } else { |
97 | | - await fs.writeFile(filePath, translatedObject, 'utf-8') |
98 | 71 | } |
99 | 72 | } catch (err) { |
100 | 73 | throw new CLIError('Unable to write file - ' + filePath + ' Error: ' + err.message) |
101 | 74 | } |
102 | | - this.log('Successfully wrote translated model to ' + filePath) |
103 | | - } |
104 | | - |
105 | | - private async generateNewFilePath(fileName: string, translatedLanguage: string, output: string): Promise<string> { |
106 | | - let outputStat = await fs.stat(output) |
107 | | - if (outputStat.isFile()) { |
108 | | - return path.join(process.cwd(), output) |
109 | | - } else { |
110 | | - let base = path.join(process.cwd(), output, translatedLanguage) |
111 | | - await fs.mkdirp(base) |
112 | | - return path.join(base, fileName) |
113 | | - } |
114 | 75 | } |
115 | 76 | } |
0 commit comments