var debug = false; function logStr(message) { if (debug) channel.message(message); } function log(message, obj) { log(message + ": " + JSON.stringify(obj)); } function getData(arg) { logStr("Getting data"); var ret = parseName(arg); log("Initial split", ret); arg = ret[1]; var obj = storage.get(ret[0]); log("obj before parsing", obj); if (!arg) { channel.message(obj); return; } try { obj = JSON.parse(obj); } catch (e) { channel.message("Data was not in json format"); return; } log("obj after parsing", obj); while (arg) { logStr("==========="); log("arg", arg); ret = parseName(arg); log("split", ret); arg = ret[1]; var name = ret[0]; if (obj === null) { channel.message("Data not found, noob"); return; } if (name in obj) obj = obj[name]; else obj = null; log("obj", obj); } channel.message(JSON.stringify(obj)); } function setData(arg) { logStr("Setting data"); var ret = parseName(arg); log("Initial split", ret); arg = ret[1]; if (!arg || arg.startsWith("=")) { if (arg.startsWith("=")) { arg = arg.substring(1); arg = skipWhitespace(arg); } logStr("No path, setting \"" + ret[0] + "\" to \"" + arg + "\""); storage.set(ret[0], arg); channel.message("Data successfully stored"); return; } var lastObj; var name = null; var obj = storage.get(ret[0]); log("obj before parsing", obj); try { obj = JSON.parse(obj); } catch (e) { channel.message("Data was not in json format"); return; } log("obj after parsing", obj); var topLevelObj = obj; log("topLevelObj", topLevelObj); while (arg && !arg.startsWith("=")) { logStr("==========="); log("arg", arg); lastObj = obj; ret = parseName(arg); log("split", ret); arg = ret[1]; name = ret[0]; if (obj === null) obj = {}; if (name in obj) obj = obj[name]; else obj = null; log("obj", obj); } if (arg.startsWith("=")) arg = arg.substring(1); arg = skipWhitespace(arg); log("value before parsing", arg); log("lastObj before set", lastObj); log("topLevelObj before set", topLevelObj); try { lastObj[name] = JSON.parse(arg); } catch (e) { channel.message("json parse error:\n" + e.message); return; } log("value after parsing", lastObj[name]); log("lastObj after set", lastObj); log("topLevelObj after set", topLevelObj); storage.set(ret[0], JSON.stringify(topLevelObj)); channel.message("Data stored"); } function deleteData(arg) { logStr("Deleting data"); var ret = parseName(arg); log("Initial split", ret); arg = ret[1]; if (!arg) { logStr("No path"); storage.delete(ret[0]); } else { var obj = storage.get(ret[0]); log("obj before parsing", obj); try { obj = JSON.parse(obj); } catch (e) { channel.message("Data was not in json format"); return; } log("obj after parsing", obj); var topLevelObj = obj; var name = null; var lastObj; while (arg) { logStr("============="); log("arg", arg); lastObj = obj; ret = parseName(arg); log("split", ret); arg = ret[1]; name = ret[0]; if (obj == null) { channel.message("Data not found, noob"); return; } if (name in obj) obj = obj[name]; else obj = null; log("obj", obj); } if (obj === null) { channel.message("Data not found, noob"); return; } log("lastObj before delete", lastObj); log("topLevelObj before delete", topLevelObj); delete lastObj[name]; log("lastObj after delete", lastObj); log("topLevelObj after delete", topLevelObj); storage.set(ret[0], JSON.stringify(topLevelObj)); } channel.message("Data deleted"); } function parseName(arg) { arg = skipWhitespace(arg); var name = ""; if (arg.startsWith("\"")) { var escaped = false; arg = arg.substring(1); while (arg) { var c = arg.charAt(0); arg = arg.substring(1); if (c == "\\") { if (!escaped) { escaped = true; } else { escaped = false; name += "\\"; } } else { if (c == "\"" && !escaped) break; name += c; escaped = false; } } arg = skipWhitespace(arg); if (arg.startsWith(".")) arg = arg.substring(1); arg = skipWhitespace(arg); return [name, arg]; } else { while (arg && !arg.startsWith("=") && !arg.startsWith(".") && !(/^\s.+$/.test(arg))) { name += arg.charAt(0); arg = arg.substring(1); } arg = skipWhitespace(arg); if (arg.startsWith(".")) arg = arg.substring(1); arg = skipWhitespace(arg); return [name, arg]; } } function skipWhitespace(arg) { while (/^\s.+$/.test(arg)) arg = arg.substring(1); return arg; } var arg = message.getContent(); if (arg.startsWith("//storage ")) arg = arg.substring(10); if (arg.startsWith("--debug ")) { arg = arg.substring(8); debug = true; } if (arg.startsWith("get ")) { getData(arg.substring(4)); } else if (arg.startsWith("set ")) { setData(arg.substring(4)); } else if (arg.startsWith("delete ")) { deleteData(arg.substring(7)); } else { channel.message("```\nUsage:\n//storage get path.to.data\n//storage set path.to.data=newValue\n//storage delete path.to.data\n```"); }