!7 static Map cmdToProgram; static Map cmdToShell; static Map cmdToAnswer; static Map cmdToCmd; static Map cmdToEval; static Map> cmdToBotSend; static L> voiceCommandLog; static IVar prioBot; p { magellan(); quietDB(); cmdToProgram = persistentTreeMap("Command to program"); cmdToShell = persistentTreeMap("Command to shell"); cmdToAnswer = persistentTreeMap("Command to answer"); cmdToCmd = persistentTreeMap("Command to command"); cmdToBotSend = persistentTreeMap("Command to bot send"); cmdToEval = persistentTreeMap("Command to eval"); prioBot = persistentVar("Prio bot"); voiceCommandLog = persistentList("Voice Command Log"); makeBot("Voice Actions."); } sS answer(S s) { new Matches m; voiceCommandLog.add(pair(s, now())); if "prio bot *" { prioBot.set($1); consoleStatus(prioBot!); ret "OK"; } if "prio bot done *" { if (eqic(prioBot!, $1)) prioBot.set(null); consoleStatus(prioBot!); ret "OK"; } if "prio bot none" { prioBot.set(null); consoleStatus(prioBot!); ret "OK"; } if "user said: *" s = $1; S a; try { a = answer2(s); } catch e { printStackTrace(e); a = str(e); } if (nempty(a)) infoBox_lower(a); ret a; } sS answer2(S s) { new Matches m; // drop "ja" or "yep" //S answerWord = dropPunctuation(botAnswerWord()); //if (matchStart(answerWord, s, m)) s = m.rest(); if (nempty(prioBot!)) pcall { try answer send(prioBot!, "User said: *", s); } Set seen; for ping (seen = new LinkedHashSet; l(seen) < 100; ) { if "command * to program *" { cmdToProgram.put($1, $2); ret "OK"; } if "command * to shell *" { cmdToShell.put($1, $2); ret "OK"; } if "command * to answer *" { cmdToAnswer.put($1, $2); ret "OK"; } if "command * send * to *" { cmdToBotSend.put($1, pair($3, $2)); ret "OK"; } if "command * to eval *" { cmdToEval.put($1, $2); ret "OK"; } if "command * to command *" { cmdToCmd.put($1, $2); ret "OK"; } if "remove command *" { removeFromMaps($1, cmdToProgram, cmdToShell, cmdToAnswer, cmdToBotSend, cmdToEval); ret "OK"; } if "applause" { applause(); ret "Applause!"; } if "restart voice actions" { restartIn1(); ret "OK"; } if "voice log" { showLog(); ret "OK"; } S program = lookupByNLMatch(cmdToProgram, s); if (nempty(program)) { nohupJavax(program); ret "Running: " + snippetWithTitle(program); } Pair botSend = lookupByNLMatch(cmdToBotSend, s); if (botSend != null) ret send(botSend.a, botSend.b); S eval = lookupByNLMatch(cmdToEval, s); if (eval != null) ret or2(strOrEmpty(evalJava(eval)), "OK"); S shell = lookupByNLMatch(cmdToShell, s); if (nempty(shell)) { nohup(shell); ret "Running: " + shell; } try answer lookupByNLMatch(cmdToAnswer, s); seen.add(s); s = lookupByNLMatch(cmdToCmd, s); if (empty(s)) null; if (seen.contains(s)) fail("bad cmd-to-cmd: " + sfu(seen)); } fail("bad cmd-to-cmd: " + sfu(seen)); } svoid showLog { showTable_updatedOnConceptsChange("Voice Log", f renderLog); } static L renderLog() { ret reversed(map(cloneList(voiceCommandLog), func(Pair p) { litorderedmap("Command" := p.a, "Time" := formatDateAndTime(p.b)) })); }