Skip to content

Commit

Permalink
scripting utterances
Browse files Browse the repository at this point in the history
  • Loading branch information
codeforequity-at committed Mar 4, 2018
1 parent d1d636d commit e189d5d
Show file tree
Hide file tree
Showing 13 changed files with 244 additions and 81 deletions.
11 changes: 11 additions & 0 deletions .tern-project
@@ -0,0 +1,11 @@
{
"ecmaVersion": 6,
"libs": [],
"loadEagerly": [],
"dontLoad": [
"node_modules/**"
],
"plugins": {
"doc_comment": true
}
}
Binary file added samples/scripting/Book2.xlsx
Binary file not shown.
10 changes: 5 additions & 5 deletions samples/scripting/botiumFluent.js
Expand Up @@ -24,16 +24,16 @@ const driver = new BotDriver()
.setCapability(Capabilities.WATSONCONVERSATION_PASSWORD, 'ZWDE5xo02sby')
.setCapability(Capabilities.WATSONCONVERSATION_WORKSPACE_ID, '97513bc0-c581-4bec-ac9f-ea6a8ec308a9')
.setCapability(Capabilities.WATSONCONVERSATION_COPY_WORKSPACE, false)
.setCapability(Capabilities.SCRIPTING_FORMAT, 'txt')
.setCapability(Capabilities.SCRIPTING_INPUT_TYPE, 'string')

const script = fs.readFileSync('./restaurant.convo.txt').toString()
const script = fs.readFileSync('./restaurant.convo.txt')

const compiler = driver.BuildCompiler()
const convos = compiler.Compile(script)
const decompiledscript = compiler.Decompile(convos)
const convos = compiler.Compile(script, 'SCRIPTING_FORMAT_TXT')
const decompiledscript = compiler.GetCompiler('SCRIPTING_FORMAT_TXT').Decompile(convos)
console.log(decompiledscript)

return

driver.BuildFluent()
.Compile(script)
.RunScripts(assert, fail)
Expand Down
8 changes: 3 additions & 5 deletions samples/scripting/botiumFluentXlsx.js
Expand Up @@ -11,14 +11,12 @@ const driver = new BotDriver()
.setCapability(Capabilities.WATSONCONVERSATION_PASSWORD, 'ZWDE5xo02sby')
.setCapability(Capabilities.WATSONCONVERSATION_WORKSPACE_ID, '97513bc0-c581-4bec-ac9f-ea6a8ec308a9')
.setCapability(Capabilities.WATSONCONVERSATION_COPY_WORKSPACE, false)
.setCapability(Capabilities.SCRIPTING_FORMAT, 'xlsx')
.setCapability(Capabilities.SCRIPTING_INPUT_TYPE, 'buffer')
.setCapability(Capabilities.SCRIPTING_XLSX_SHEETNAMES, '2-Schritt-Dialoge | 3-Schritt-Dialoge')
.setCapability(Capabilities.SCRIPTING_XLSX_STARTROW, 2)
.setCapability(Capabilities.SCRIPTING_XLSX_STARTCOL, 1)


const script = fs.readFileSync('./Book1.xlsx')

const convos = driver.BuildCompiler().Compile(script)
const convos = driver.BuildCompiler().Compile(script, 'SCRIPTING_FORMAT_XSLX')
console.log(JSON.stringify(convos, null, 2))
25 changes: 25 additions & 0 deletions samples/scripting/botiumFluentXlsxUtt.js
@@ -0,0 +1,25 @@
const fs = require('fs')

const BotDriver = require('../../index').BotDriver
const Capabilities = require('../../index').Capabilities
const Source = require('../../index').Source

const driver = new BotDriver()
.setCapability(Capabilities.PROJECTNAME, 'IBM Watson Conversation Sample')
.setCapability(Capabilities.CONTAINERMODE, 'watsonconversation')
.setCapability(Capabilities.WATSONCONVERSATION_USER, '0274cb6f-3680-4cf7-bd6b-71c7f447542d')
.setCapability(Capabilities.WATSONCONVERSATION_PASSWORD, 'ZWDE5xo02sby')
.setCapability(Capabilities.WATSONCONVERSATION_WORKSPACE_ID, '97513bc0-c581-4bec-ac9f-ea6a8ec308a9')
.setCapability(Capabilities.WATSONCONVERSATION_COPY_WORKSPACE, false)
.setCapability(Capabilities.SCRIPTING_XLSX_SHEETNAMES, 'Dialogs')
.setCapability(Capabilities.SCRIPTING_XLSX_SHEETNAMES_UTTERANCES, 'Utterances')
.setCapability(Capabilities.SCRIPTING_XLSX_STARTROW, 2)
.setCapability(Capabilities.SCRIPTING_XLSX_STARTCOL, 1)


const script = fs.readFileSync('./Book2.xlsx')
const compiler = driver.BuildCompiler()
//compiler.Compile(script, 'SCRIPTING_FORMAT_XSLX', 'SCRIPTING_TYPE_CONVO')
//console.log(JSON.stringify(compiler.convos, null, 2))
compiler.Compile(script, 'SCRIPTING_FORMAT_XSLX', 'SCRIPTING_TYPE_UTTERANCES')
console.log(JSON.stringify(compiler.utterances, null, 2))
15 changes: 7 additions & 8 deletions src/BotDriver.js
Expand Up @@ -13,6 +13,7 @@ const Capabilities = require('./Capabilities')
const Source = require('./Source')
const Fluent = require('./Fluent')
const Events = require('./Events')
const ScriptingProvider = require('./scripting/ScriptingProvider')

module.exports = class BotDriver {
constructor (caps = {}, sources = {}, env = {}) {
Expand Down Expand Up @@ -117,15 +118,13 @@ module.exports = class BotDriver {
}

BuildCompiler () {
if (this.caps[Capabilities.SCRIPTING_FORMAT] === 'xlsx') {
const CompilerXlsx = require('./scripting/CompilerXlsx')
return new CompilerXlsx(this.caps)
debug(`BuildCompiler: Capabilites: ${util.inspect(this.caps)}`)
try {
return (new ScriptingProvider(this.caps)).Build()
} catch (err) {
debug(`BotDriver BuildCompiler error: ${err}`)
throw err
}
if (this.caps[Capabilities.SCRIPTING_FORMAT] === 'txt') {
const CompilerTxt = require('./scripting/CompilerTxt')
return new CompilerTxt(this.caps)
}
throw new Error(`No compiler found for caps ${util.inspect(this.caps)}`)
}

/* Private Functions */
Expand Down
5 changes: 1 addition & 4 deletions src/Capabilities.js
Expand Up @@ -75,13 +75,10 @@ module.exports = {
DIALOGFLOW_LANGUAGE_CODE: 'DIALOGFLOW_LANGUAGE_CODE',
DIALOGFLOW_USE_INTENT: 'DIALOGFLOW_USE_INTENT',
// Script Compiler
// "txt" "xlsx" "yaml"
SCRIPTING_FORMAT: 'SCRIPTING_FORMAT',
// "base64" "binary" "string" "buffer" "array" "file"
SCRIPTING_INPUT_TYPE: 'SCRIPTING_INPUT_TYPE',
SCRIPTING_TXT_EOL: 'SCRIPTING_TXT_EOL',
SCRIPTING_XLSX_STARTROW: 'SCRIPTING_XLSX_STARTROW',
SCRIPTING_XLSX_STARTCOL: 'SCRIPTING_XLSX_STARTCOL',
SCRIPTING_XLSX_SHEETNAMES: 'SCRIPTING_XLSX_SHEETNAMES',
SCRIPTING_XLSX_SHEETNAMES_UTTERANCES: 'SCRIPTING_XLSX_SHEETNAMES_UTTERANCES',
SCRIPTING_NORMALIZE_TEXT: 'SCRIPTING_NORMALIZE_TEXT'
}
12 changes: 5 additions & 7 deletions src/scripting/CompilerBase.js
@@ -1,24 +1,22 @@
const Capabilities = require('../Capabilities')

module.exports = class CompilerBase {
constructor (caps = {}) {
constructor (provider, caps = {}) {
this.provider = provider
this.caps = caps
}

Validate () {
this._AssertCapabilityExists(Capabilities.SCRIPTING_INPUT_TYPE)
}

GetHeaders (scriptData) {
const convos = this.Compile(scriptData)
GetHeaders (scriptBuffer) {
const convos = this.Compile(scriptBuffer)
if (convos) {
return convos.map((convo) => convo.header)
} else {
return []
}
}

Compile (scriptData) {
Compile (scriptBuffer, scriptType) {
throw new Error(`not implemented`)
}

Expand Down
24 changes: 13 additions & 11 deletions src/scripting/CompilerTxt.js
Expand Up @@ -2,25 +2,26 @@ const isJSON = require('is-json')
const _ = require('lodash')

const Capabilities = require('../Capabilities')
const Constants = require('./Constants')
const CompilerBase = require('./CompilerBase')
const { ConvoHeader, Convo } = require('./Convo')

module.exports = class CompilerTxt extends CompilerBase {
constructor (caps = {}) {
super(caps)
constructor (provider, caps = {}) {
super(provider, caps)

this.eol = caps[Capabilities.SCRIPTING_TXT_EOL]
}

Validate () {
super.Validate()
this._AssertCapabilityExists(Capabilities.SCRIPTING_TXT_EOL)
if (this.caps[Capabilities.SCRIPTING_INPUT_TYPE] !== 'buffer' && this.caps[Capabilities.SCRIPTING_INPUT_TYPE] !== 'string') {
throw new Error(`SCRIPTING_INPUT_TYPE(${this.caps[Capabilities.SCRIPTING_INPUT_TYPE]}) only buffer and string type supported`)
}
}

GetHeaders (scriptData) {
GetHeaders (scriptBuffer) {
let scriptData = scriptBuffer
if (Buffer.isBuffer(scriptBuffer)) scriptData = scriptData.toString()

let lines = scriptData.split(this.eol)

let header = { }
Expand All @@ -31,10 +32,9 @@ module.exports = class CompilerTxt extends CompilerBase {
return new ConvoHeader(header)
}

Compile (scriptData) {
if (this.caps[Capabilities.SCRIPTING_INPUT_TYPE] === 'buffer') {
scriptData = scriptData.toString()
}
Compile (scriptBuffer, scriptType = Constants.SCRIPTING_TYPE_CONVO) {
let scriptData = scriptBuffer
if (Buffer.isBuffer(scriptBuffer)) scriptData = scriptData.toString()

let lines = scriptData.split(this.eol)

Expand Down Expand Up @@ -101,7 +101,9 @@ module.exports = class CompilerTxt extends CompilerBase {
})
pushPrev()

return [ new Convo(convo) ]
let result = [ new Convo(convo) ]
this.provider.AddConvos(result)
return result
}

Decompile (convos) {
Expand Down
128 changes: 87 additions & 41 deletions src/scripting/CompilerXlsx.js
Expand Up @@ -5,11 +5,13 @@ const debug = require('debug')('botium-CompilerXlsx')

const Capabilities = require('../Capabilities')
const CompilerBase = require('./CompilerBase')
const Constants = require('./Constants')
const Utterance = require('./Utterance')
const { Convo } = require('./Convo')

module.exports = class CompilerXlsx extends CompilerBase {
constructor (caps = {}) {
super(caps)
constructor (provider, caps = {}) {
super(provider, caps)

this.colnames = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ]
}
Expand All @@ -26,18 +28,29 @@ module.exports = class CompilerXlsx extends CompilerBase {
}
}

Compile (scriptData) {
const workbook = XLSX.read(scriptData, { type: this.caps[Capabilities.SCRIPTING_INPUT_TYPE] })

Compile (scriptBuffer, scriptType = Constants.SCRIPTING_TYPE_CONVO) {
const workbook = XLSX.read(scriptBuffer, { type: 'buffer' })
if (!workbook) throw new Error(`Workbook not readable`)

let sheetnames = workbook.SheetNames
if (this.caps[Capabilities.SCRIPTING_XLSX_SHEETNAMES]) {
sheetnames = this.caps[Capabilities.SCRIPTING_XLSX_SHEETNAMES].split(/\s*[;,\s|]\s*/)
let sheetnames = []
if (scriptType === Constants.SCRIPTING_TYPE_CONVO) {
if (this.caps[Capabilities.SCRIPTING_XLSX_SHEETNAMES]) {
sheetnames = this.caps[Capabilities.SCRIPTING_XLSX_SHEETNAMES].split(/\s*[;,\s|]\s*/) || []
} else {
sheetnames = workbook.SheetNames || []
}
}
if (scriptType === Constants.SCRIPTING_TYPE_UTTERANCES) {
if (this.caps[Capabilities.SCRIPTING_XLSX_SHEETNAMES_UTTERANCES]) {
sheetnames = this.caps[Capabilities.SCRIPTING_XLSX_SHEETNAMES_UTTERANCES].split(/\s*[;,\s|]\s*/) || []
} else {
sheetnames = workbook.SheetNames || []
}
}
debug(`sheet names: ${util.inspect(sheetnames)}`)
debug(`sheet names for ${scriptType}: ${util.inspect(sheetnames)}`)

const scriptResults = []

const convos = []
sheetnames.forEach((sheetname) => {
const sheet = workbook.Sheets[sheetname]
if (!sheet) return
Expand All @@ -47,41 +60,74 @@ module.exports = class CompilerXlsx extends CompilerBase {
if (_.isString(this.caps[Capabilities.SCRIPTING_XLSX_STARTCOL])) {
colindex = this.colnames.findIndex((c) => c === this.caps[Capabilities.SCRIPTING_XLSX_STARTCOL])
}
debug(`evaluating sheet name: ${util.inspect(sheetname)}, rowindex ${rowindex}, colindex ${colindex}`)

let currentConvo = []
let emptylines = 0
let startcell = null
while (true) {
const meCell = this.colnames[colindex] + rowindex
const botCell = this.colnames[colindex + 1] + rowindex

if (sheet[meCell] && sheet[meCell].v) {
currentConvo.push({ sender: 'me', messageText: sheet[meCell].v, stepTag: 'Cell ' + meCell })
if (!startcell) startcell = meCell
emptylines = 0
} else if (sheet[botCell] && sheet[botCell].v) {
currentConvo.push({ sender: 'bot', messageText: sheet[botCell].v, stepTag: 'Cell ' + botCell })
if (!startcell) startcell = botCell
emptylines = 0
} else {
if (currentConvo.length > 0) {
convos.push(new Convo({
header: {
name: `${sheetname}-${startcell}`
},
conversation: currentConvo
}))
debug(`evaluating sheet name for ${scriptType}: ${util.inspect(sheetname)}, rowindex ${rowindex}, colindex ${colindex}`)

if (scriptType === Constants.SCRIPTING_TYPE_CONVO) {
let currentConvo = []
let emptylines = 0
let startcell = null
while (true) {
const meCell = this.colnames[colindex] + rowindex
const botCell = this.colnames[colindex + 1] + rowindex

if (sheet[meCell] && sheet[meCell].v) {
currentConvo.push({ sender: 'me', messageText: sheet[meCell].v, stepTag: 'Cell ' + meCell })
if (!startcell) startcell = meCell
emptylines = 0
} else if (sheet[botCell] && sheet[botCell].v) {
currentConvo.push({ sender: 'bot', messageText: sheet[botCell].v, stepTag: 'Cell ' + botCell })
if (!startcell) startcell = botCell
emptylines = 0
} else {
if (currentConvo.length > 0) {
scriptResults.push(new Convo({
header: {
name: `${sheetname}-${startcell}`
},
conversation: currentConvo
}))
}
currentConvo = []
startcell = null
emptylines++
}
currentConvo = []
startcell = null
emptylines++
rowindex++

if (emptylines > 1) break
}
rowindex++
}

if (scriptType === Constants.SCRIPTING_TYPE_UTTERANCES) {
let currentUtterance = null
let emptylines = 0
while (true) {
const nameCell = this.colnames[colindex] + rowindex
const uttCell = this.colnames[colindex + 1] + rowindex

if (sheet[nameCell] && sheet[nameCell].v && sheet[uttCell] && sheet[uttCell].v) {
currentUtterance = new Utterance({ name: sheet[nameCell].v, utterances: [ sheet[uttCell].v ] })
scriptResults.push(currentUtterance)
emptylines = 0
} else if (sheet[uttCell] && sheet[uttCell].v) {
if (currentUtterance) currentUtterance.utterances.push(sheet[uttCell].v)
emptylines = 0
} else {
currentUtterance = null
emptylines++
}
rowindex++

if (emptylines > 1) break
if (emptylines > 1) break
}
}
})
return convos

if (scriptType === Constants.SCRIPTING_TYPE_CONVO) {
this.provider.AddConvos(scriptResults)
}
if (scriptType === Constants.SCRIPTING_TYPE_UTTERANCES) {
this.provider.AddUtterances(scriptResults)
}
return scriptResults
}
}
7 changes: 7 additions & 0 deletions src/scripting/Constants.js
@@ -0,0 +1,7 @@
module.exports = {
SCRIPTING_FORMAT_XSLX: 'SCRIPTING_FORMAT_XSLX',
SCRIPTING_FORMAT_TXT: 'SCRIPTING_FORMAT_TXT',
SCRIPTING_FORMAT_YAML: 'SCRIPTING_FORMAT_YAML',
SCRIPTING_TYPE_CONVO: 'SCRIPTING_TYPE_CONVO',
SCRIPTING_TYPE_UTTERANCES: 'SCRIPTING_TYPE_UTTERANCES'
}

0 comments on commit e189d5d

Please sign in to comment.