!752 static S dataProgID = "#1002143"; // use data dir of "These Are Bot" v1 (don't use both bots at once...) // TODO: make a PersistentMultiMap? static new MultiMap lists; static new MultiMap notLists; p { load(dataProgID, "lists"); load(dataProgID, "notLists"); makeBot("These Are Bot."); } synchronized answer { L tok = javaTok(s); if (eqic(get(tok, 1), "these") && eqic(get(tok, 3), "are") && eqic(get(tok, 7), ":")) { S kind = unquote(get(tok, 5)); L rest = subList(tok, 8); ret addThem(kind, rest, true); } if (eqic(get(tok, 1), "these") && eqic(get(tok, 3), "are") && eqic(get(tok, 5), "not") && eqic(get(tok, 9), ":")) { S kind = unquote(get(tok, 7)); L rest = subList(tok, 10); ret addThem(kind, rest, false); } if (match("name a *", s, m)) { S kind = singular(simplify(m.unq(0))); L items = lists.get(kind); if (empty(items)) ret null; //"I don't know any " + m.unq(0); ret randomOne(items); } if (match("name * *", s, m)) { S n = m.get(0); if (isInteger(n)) { int _n = min(100, parseInt(n)); S kind = singular(simplify(m.unq(1))); L items = cloneList(lists.get(kind)); if (l(items) < _n) ret "I don't know that many " + m.unq(1); new L l; for (int i = 0; i < _n; i++) { S x = randomOne(items); l.add(x); items.remove(x); } ret join(", ", l); } } S userName = cast callOpt(mainBot, "getUserName"); if (match("am i a *", s, m)) { if (empty(userName)) ret "Well I don't know who you are! Please join slack.com"; S kind = m.unq(0); boolean result = containsIgnoreCase(lists.get(kind), userName) || containsIgnoreCase(lists.get(kind), dropPrefix("@", userName)); if (result) ret format("Yes, you are a *!", kind); else ret format("As far as I know, you are not a *.", kind); } if (match("is * a *", s, m)) { S instance = m.unq(0); S kind = singular(simplify(m.unq(1))); boolean result = containsIgnoreCase(lists.get(kind), instance); if (result) ret format("Yes, * is a *", instance, kind); else ret null; //ret format("I don't know that * is a *", instance, kind); } if (match("Are there any * other than *?", s, m)) { S kind = singular(simplify(m.unq(0))); S instance = m.unq(1); L items = cloneList(lists.get(kind)); removeIgnoreCase(items, instance); if (empty(items)) ret format("No, * is the only *.", instance, kind); else ret format("Yes, for example *", randomOne(items)); } if (match("list all *", s, m)) { S kind = singular(simplify(m.unq(0))); L items = lists.get(kind); if (empty(items)) ret null; // format("I don't know any *", kind); else ret join(", ", items); } if (match("list all ex *", s, m)) { S kind = singular(simplify(m.unq(0))); L items = notLists.get(kind); if (empty(items)) ret null; // format("I don't know any ex *", kind); else ret join(", ", items); } } static S simplify(S s) { ret toLower(s); } static S singular(S s) { if (s.endsWith("ies")) ret dropSuffix("ies", s) + "y"; ret dropSuffix("s", s); } static S addThem(S kind, L rest, boolean plus) { kind = singular(simplify(kind)); boolean comma = rest.contains(","); new L items; if (comma) for (L item : splitListBy(rest, ",")) items.add(trim(join(simpleSpaces(item)))); else items.addAll(codeTokensOnly(rest)); printFormat((plus ? "Adding" : "Removing") + " items * to/from kind *", items, kind); (plus ? lists : notLists).addAllIfNotThere(kind, items); (plus ? notLists : lists).removeAll(kind, items); save(dataProgID, "lists"); save(dataProgID, "notLists"); ret format("OK, now " + l(lists.get(kind)) + " items in kind *", kind); }