Skip to content
This repository was archived by the owner on Jan 15, 2025. It is now read-only.

Commit 9b464b8

Browse files
committed
Adding object processing ability to translate commands
1 parent 6304a6c commit 9b464b8

File tree

8 files changed

+108
-114
lines changed

8 files changed

+108
-114
lines changed

packages/luis/src/commands/luis/generate/cs.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import {camelCase, upperFirst} from 'lodash'
33
import * as path from 'path'
44

55
import {LuisToCsConverter} from '../../../parser/converters/luis-to-cs-converter'
6-
import {Utils} from '../../../utils'
76

7+
const file = require('./../../../utils/filehelper')
88
const fs = require('fs-extra')
99

1010
export default class LuisGenerateCs extends Command {
@@ -52,7 +52,7 @@ export default class LuisGenerateCs extends Command {
5252
this.reorderEntities(app, 'patternAnyEntities')
5353
this.reorderEntities(app, 'composites')
5454

55-
const outputPath = Utils.validatePath(flags.out, process.cwd(), flags.className + '.cs', flags.force)
55+
const outputPath = file.validatePath(flags.out, flags.className + '.cs', flags.force)
5656

5757
this.log(
5858
`Generating file at ${outputPath || ''} that contains class ${space}.${flags.className}.`

packages/luis/src/commands/luis/generate/ts.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import {camelCase, kebabCase, upperFirst} from 'lodash'
33
import * as path from 'path'
44

55
import {LuisToTsConverter} from '../../../parser/converters/luis-to-ts-converter'
6-
import {Utils} from '../../../utils'
76

7+
const file = require('./../../../utils/filehelper')
88
const fs = require('fs-extra')
99

1010
export default class LuisGenerateTs extends Command {
@@ -45,7 +45,7 @@ export default class LuisGenerateTs extends Command {
4545
this.reorderEntities(app, 'patternAnyEntities')
4646
this.reorderEntities(app, 'composites')
4747

48-
const outputPath = Utils.validatePath(flags.out, process.cwd(), kebabCase(flags.className) + '.ts', flags.force)
48+
const outputPath = file.validatePath(flags.out, kebabCase(flags.className) + '.ts', flags.force)
4949

5050
this.log(
5151
`Generating file at ${outputPath || ''} that contains class ${flags.className}.`

packages/luis/src/commands/luis/translate.ts

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,41 @@ export default class LuisTranslate extends Command {
2525
async run() {
2626
try {
2727
const {flags} = this.parse(LuisTranslate)
28-
let inputStat = await fs.stat(flags.in)
28+
// Check if data piped in stdin
29+
let stdin = await this.readStdin()
2930
let outputStat = flags.out ? await fs.stat(flags.out) : null
3031

3132
if (outputStat && outputStat.isFile()) {
3233
throw new CLIError('Output can only be writen to a folder')
3334
}
3435

35-
let isLu = !inputStat.isFile() ? true : path.extname(flags.in) === '.lu'
36+
let isLu = await fileHelper.detectLuContent(stdin, flags.in)
3637
let result: any
3738
if (isLu) {
38-
let luFiles = await fileHelper.getLuFiles(flags.in, flags.recurse)
39-
result = await luTranslator.translateLuFile(luFiles, flags.translatekey, flags.tgtlang, flags.srclang, flags.translate_comments, flags.translate_link_text)
39+
let luFiles = await fileHelper.getLuObjects(stdin, flags.in, flags.recurse)
40+
result = await luTranslator.translateLuList(luFiles, flags.translatekey, flags.tgtlang, flags.srclang, flags.translate_comments, flags.translate_link_text)
4041
} else {
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)
46-
})
42+
let json = stdin ? stdin : await fileHelper.getContentFromFile(flags.in)
43+
let translation = await luisConverter.parseLuisObjectToLu(json, false)
44+
translation = await luTranslator.translateLuObj(translation, flags.translatekey, flags.tgtlang, flags.srclang, flags.translate_comments, flags.translate_link_text)
45+
let key = stdin ? 'stdin' : path.basename(flags.in)
46+
result = {
47+
[key] : {}
48+
}
49+
for (let lng in translation) {
50+
let translatedJSON = await luConverter.parseFile(translation[lng], false)
51+
result[key][lng] = await translatedJSON.LUISJsonStructure
52+
}
4753
}
4854

4955
if (flags.out) {
5056
await this.writeOutput(result, flags.out)
5157
} else {
52-
this.log(result)
58+
if (isLu) {
59+
this.log(result)
60+
} else {
61+
this.log(JSON.stringify(result, null, 2))
62+
}
5363
}
5464

5565
} catch (err) {
@@ -66,7 +76,7 @@ export default class LuisTranslate extends Command {
6676
for (let file in translatedObject) {
6777
for (let lng in translatedObject[file]) {
6878
filePath = await fileHelper.generateNewTranslatedFilePath(file, lng, out)
69-
await fs.writeFile(filePath, translatedObject[path.basename(file)][lng][0], 'utf-8')
79+
await fs.writeFile(filePath, translatedObject[file][lng], 'utf-8')
7080
}
7181
}
7282
} catch (err) {

packages/luis/src/commands/qnamaker/translate.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,41 @@ export default class QnamakerTranslate extends Command {
2525
async run() {
2626
try {
2727
const {flags} = this.parse(QnamakerTranslate)
28-
let inputStat = await fs.stat(flags.in)
28+
// Check if data piped in stdin
29+
let stdin = await this.readStdin()
2930
let outputStat = flags.out ? await fs.stat(flags.out) : null
3031

3132
if (outputStat && outputStat.isFile()) {
3233
throw new CLIError('Output can only be writen to a folder')
3334
}
3435

35-
let isLu = !inputStat.isFile() ? true : path.extname(flags.in) === '.lu'
36+
let isLu = await fileHelper.detectLuContent(stdin, flags.in)
3637
let result: any
3738
if (isLu) {
38-
const luFiles = await fileHelper.getLuFiles(flags.in, flags.recurse)
39-
result = await luTranslator.translateLuFile(luFiles, flags.translatekey, flags.tgtlang, flags.srclang, flags.translate_comments, flags.translate_link_text)
39+
let luFiles = await fileHelper.getLuObjects(stdin, flags.in, flags.recurse)
40+
result = await luTranslator.translateLuList(luFiles, flags.translatekey, flags.tgtlang, flags.srclang, flags.translate_comments, flags.translate_link_text)
4041
} else {
41-
let translation = await qnaConverter.parseQnAFileToLu(flags.in, false, false)
42+
let json = stdin ? stdin : await fileHelper.getContentFromFile(flags.in)
43+
let translation = await qnaConverter.parseQnAObjectToLu(json, false)
4244
translation = await luTranslator.translateLuObj(translation, 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)
46-
})
45+
let key = stdin ? 'stdin' : path.basename(flags.in)
46+
result = {
47+
[key] : {}
48+
}
49+
for (let lng in translation) {
50+
let translatedJSON = await luConverter.parseFile(translation[lng], false)
51+
result[key][lng] = await translatedJSON.qnaJsonStructure
52+
}
4753
}
4854

4955
if (flags.out) {
5056
await this.writeOutput(result, flags.out)
5157
} else {
52-
this.log(JSON.stringify(result, null, 2))
58+
if (isLu) {
59+
this.log(result)
60+
} else {
61+
this.log(JSON.stringify(result, null, 2))
62+
}
5363
}
5464

5565
} catch (err) {

packages/luis/src/parser/luisfile/parseLuisFile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ module.exports = {
1010
try {
1111
LUISJSON = await JSON.parse(LUISFileContent);
1212
} catch (err) {
13-
throw (new exception(retCode.errorCode.INVALID_INPUT_FILE, 'Sorry, error parsing file as LUIS JSON: ' + file));
13+
throw (new exception(retCode.errorCode.INVALID_INPUT_FILE, 'Sorry, error parsing file as LUIS JSON'));
1414
}
1515
await validateLUISJSON(LUISJSON)
1616
return LUISJSON;

packages/luis/src/parser/translator/lutranslate.js

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ const retCode = require('./../lufile/enums/CLI-errors')
66
const translateHelpers = require('./../lufile/translate-helpers')
77

88
module.exports = {
9-
translateLuFile: async function(files, translate_key, to_lang, src_lang, translate_comments, translate_link_text) {
9+
translateLuList: async function(files, translate_key, to_lang, src_lang, translate_comments, translate_link_text) {
1010
let translation = {}
1111
let i = 0
1212
while(files.length > i) {
13-
let file = files[i++] + ''
13+
let luObject = files[i++]
1414
try {
15-
let luObject = await parseFile(file)
16-
translation[path.basename(file)] = await this.translateLuObj(luObject, translate_key, to_lang, src_lang, translate_comments, translate_link_text)
15+
translation[path.basename(luObject.id)] = await this.translateLuObj(luObject.content, translate_key, to_lang, src_lang, translate_comments, translate_link_text)
1716
} catch (err) {
1817
throw(err);
1918
}
@@ -71,11 +70,8 @@ async function translateLuObject(luObject, translate_key, to_lang, src_lang, tra
7170
if (!parsedLocContent) {
7271
throw(new exception(retCode.errorCode.INVALID_INPUT_FILE, 'Sorry, file : ' + file + 'had invalid content'));
7372
}
74-
if (!result[tgt_lang]) {
75-
result[tgt_lang] = []
76-
}
77-
result[tgt_lang].push(parsedLocContent)
78-
73+
74+
result[tgt_lang] = parsedLocContent
7975
}
8076
return result
8177
}

packages/luis/src/utils.ts

Lines changed: 0 additions & 44 deletions
This file was deleted.

packages/luis/src/utils/filehelper.ts

Lines changed: 56 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,22 @@ const helpers = require('./../parser/lufile/helpers')
55
const luObject = require('./../parser/lufile/classes/luObject')
66
/* tslint:disable:prefer-for-of no-unused*/
77

8-
export async function getLuFiles(input: string | undefined, recurse = false): Promise<Array<any>> {
8+
export async function getLuObjects(stdin: string, input: string | undefined, recurse = false) {
9+
let luObjects: any = []
10+
if (stdin) {
11+
luObjects.push(new luObject('stdin', stdin))
12+
} else {
13+
let luFiles = await getLuFiles(input, recurse)
14+
for (let i = 0; i < luFiles.length; i++) {
15+
let luContent = await getContentFromFile(luFiles[i])
16+
luObjects.push(new luObject(path.resolve(luFiles[i]), luContent))
17+
}
18+
}
19+
20+
return luObjects
21+
}
22+
23+
async function getLuFiles(input: string | undefined, recurse = false): Promise<Array<any>> {
924
let filesToParse = []
1025
let fileStat = await fs.stat(input)
1126
if (fileStat.isFile()) {
@@ -25,28 +40,13 @@ export async function getLuFiles(input: string | undefined, recurse = false): Pr
2540
return filesToParse
2641
}
2742

28-
export async function getLuObjects(stdin: string, input: string | undefined, recurse = false) {
29-
let luObjects: any = []
30-
if (stdin) {
31-
luObjects.push(new luObject('stdin', stdin))
32-
} else {
33-
let luFiles = await getLuFiles(input, recurse)
34-
for (let i = 0; i < luFiles.length; i++) {
35-
let luContent = await readLuFile(luFiles[i])
36-
luObjects.push(new luObject(path.resolve(luFiles[i]), luContent))
37-
}
38-
}
39-
40-
return luObjects
41-
}
42-
4343
export async function getContentFromFile(file: string) {
4444
// catch if input file is a folder
4545
if (fs.lstatSync(file).isDirectory()) {
46-
throw new CLIError('Sorry, "' + file + '" is a directory! Please try a LUIS/ QnA Maker JSON file as input.')
46+
throw new CLIError('Sorry, "' + file + '" is a directory! Unable to read as a file')
4747
}
4848
if (!fs.existsSync(path.resolve(file))) {
49-
throw new CLIError('Sorry unable to open [' + file + ']')
49+
throw new CLIError('Sorry [' + file + '] does not exist')
5050
}
5151
let fileContent
5252
try {
@@ -58,7 +58,7 @@ export async function getContentFromFile(file: string) {
5858
}
5959

6060
export async function generateNewFilePath(outFileName: string, inputfile: string, isLu: boolean, prefix = ''): Promise<string> {
61-
let base = !path.isAbsolute(outFileName) ? path.join(process.cwd(), outFileName) : outFileName
61+
let base = path.resolve(outFileName)
6262
let extension = path.extname(base)
6363
if (extension) {
6464
let root = path.dirname(base)
@@ -77,27 +77,49 @@ export async function generateNewFilePath(outFileName: string, inputfile: string
7777
}
7878

7979
export async function generateNewTranslatedFilePath(fileName: string, translatedLanguage: string, output: string): Promise<string> {
80-
let newPath = ''
81-
if (!path.isAbsolute(output)) {
82-
newPath = path.join(process.cwd(), '')
83-
}
84-
80+
let newPath = path.resolve(output)
8581
newPath = path.join(output, translatedLanguage)
8682
await fs.mkdirp(newPath)
8783
return path.join(newPath, fileName)
8884
}
8985

90-
async function readLuFile(file: string) {
91-
if (!fs.existsSync(path.resolve(file))) {
92-
throw new CLIError(`Sorry unable to open [${file}]`)
93-
}
94-
let fileContent
95-
try {
96-
fileContent = await utils.readTextFile(file)
97-
} catch (err) {
98-
throw new CLIError(`Sorry, error reading file: ${file}`)
86+
export function validatePath(outputPath: string, defaultFileName: string, forceWrite = false): string {
87+
let completePath = path.resolve(outputPath)
88+
const containingDir = path.dirname(completePath)
89+
90+
// If the cointaining folder doesnt exist
91+
if (!fs.existsSync(containingDir)) throw new CLIError(`Containing directory path doesn't exist: ${containingDir}`)
92+
93+
const baseElement = path.basename(completePath)
94+
const pathAlreadyExist = fs.existsSync(completePath)
95+
96+
// If the last element in the path is a file
97+
if (baseElement.includes('.')) {
98+
return pathAlreadyExist && !forceWrite ? enumerateFileName(completePath) : completePath
9999
}
100-
return fileContent
100+
101+
// If the last element in the path is a folder
102+
if (!pathAlreadyExist) throw new CLIError(`Target directory path doesn't exist: ${completePath}`)
103+
completePath = path.join(completePath, defaultFileName)
104+
return fs.existsSync(completePath) && !forceWrite ? enumerateFileName(completePath) : completePath
105+
}
106+
107+
function enumerateFileName(filePath: string): string {
108+
const fileName = path.basename(filePath)
109+
const containingDir = path.dirname(filePath)
110+
111+
if (!fs.existsSync(containingDir)) throw new CLIError(`Containing directory path doesn't exist: ${containingDir}`)
112+
113+
const extension = path.extname(fileName)
114+
const baseName = path.basename(fileName, extension)
115+
let nextNumber = 0
116+
let newPath = ''
117+
118+
do {
119+
newPath = path.join(containingDir, baseName + `(${++nextNumber})` + extension)
120+
} while (fs.existsSync(newPath))
121+
122+
return newPath
101123
}
102124

103125
export async function detectLuContent(stdin: string, input: string) {

0 commit comments

Comments
 (0)