Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

328
LINES

< > BotCompany Repo | #1002762 // Theories Storing Bot (LIVE)

JavaX source code [tags: use-pretranspiled] - run with: x30.jar

Libraryless. Click here for Pure Java version (3185L/20K/67K).

!759

static PersistentMap<S, S> theories; // name -> text
static new MultiMap<S, S> signMap;

static new Map<S, S> icCache; // lower case name -> text

static class Sign {
  S user, theory, as;
  long since;
}

static new L<Sign> signList; // v2 of signMap

static boolean printTimings = false;

p {
  theories = new PersistentMap("theories");
  for (S name : getTheoryNames()) icCache.put(name.toLowerCase(), theories.get(name));
  load("signMap");
  load("signList");
}

static synchronized L<S> getTheoryNames() {
  ret new ArrayList(theories.keySet());
}

static synchronized boolean hasTheory(S name) {
  ret icCache.containsKey(name.toLowerCase());
}

static synchronized S getTheoryOpt(S name) {
  ret icCache.get(name.toLowerCase());
}

static synchronized S getTheory(S name) {
  S text = getTheoryOpt(name);
  if (text == null) fail("Theory * not found", name);
  ret text;
}

static synchronized L<S> getTheoriesSignedByAs(S user, S as) {
  new L<S> l;
  for (Sign s : signList)
    if (eq(s.user, user) && eq(s.as, as))
      l.add(s.theory);
  ret l;
}

static synchronized Sign findSigning(S user, S as, S theory) {
  for (Sign s : signList)
    if (eq(s.user, user) && eq(s.as, as) && eq(s.theory, theory))
      ret s;
  ret null;
}

static synchronized void theoriesPut(S name, S text) {
  theories.put(name, text);
  icCache.put(name.toLowerCase(), text);
}

static synchronized void theoriesRemove(S name) {
  theories.remove(name);
  icCache.remove(name.toLowerCase());
}

static S signTheory(S user, S theory, S as) {
  if (empty(user)) ret "go to slack please";
  if (!hasTheory(theory)) ret "Theory not found";
  if (getTheoriesSignedByAs(user, as).contains(theory))
    ret "You have already signed this theory as " + as + "!";
  new Sign sign;
  sign.user = user;
  sign.theory = theory;
  sign.as = as;
  sign.since = now();
  signList.add(sign);
  save("signList");
  ret format("OK, signed * as *!", theory, as);
}

static S unsignTheory(S user, S theory, S as) {
  if (empty(user)) ret "go to slack please";
  if (!hasTheory(theory)) ret "Theory not found";
  Sign sign = findSigning(user, as, theory);
  if (sign == null)
    ret "You have not signed this theory as " + as + ".";
  signList.remove(sign);
  save("signList");
  ret format("OK, unsigned * as *.", theory, as);
}

synchronized answer {
  //if (!attn()) ret null;
  
  if "count theories"
    ret lstr(theories);
    
  if "list theories"
    ret structure(keys(theories));
    
  if "show theory *" exceptionToUser {
    ret showTheories(litlist(m.unq(0)));
  }
  
  if (matchStart("show theories", s, m)) exceptionToUser {
    ret showTheories(codeTokensOnly(javaTok(m.rest())));
  }
  
  if "modify theory * *" exceptionToUser {
    S name = m.unq(0), text = m.unq(1);
    ret saveTheory(name, text, true);
  }
  
  if "add theory * *" exceptionToUser {
    S name = m.unq(0), text = m.unq(1);
    ret saveTheory(name, text, false);
  }
  
  S line = firstLine(s).trim();
  if (startsWithIgnoreCase(line, "theory ") && l(toLines(s)) > 1) exceptionToUser {
    line = dropPrefixIgnoreCase("theory ", line);
    line = dropSuffix(":", line).trim();
    S name = unquote(line), text = dropFirstLine(s);
    ret saveTheory(name, text, false);
  }
  
  if (match("inc theory * *", s, m) || match("increment theory * *", s, m)) exceptionToUser {
    S name = m.unq(0), text = m.unq(1);
    ret incrementTheory(name, text);
  }
  
  if "sign theory *" exceptionToUser {
    S user = getUserName();
    ret signTheory(user, m.unq(0), "default");
  }
  
  if "unsign theory *" exceptionToUser {
    S user = getUserName();
    ret unsignTheory(user, m.unq(0), "default");
  }
  
  if "sign theory * as *" exceptionToUser {
    S user = getUserName();
    ret signTheory(user, m.unq(0), m.unq(1));
  }
  
  if "unsign theory * as *" exceptionToUser {
    S user = getUserName();
    ret unsignTheory(user, m.unq(0), m.unq(1));
  }
  
  if "my signed theories" exceptionToUser {
    S user = getUserName();
    if (empty(user)) ret "go to slack please";
    ret structure(getTheoriesSignedByAs(user, "default"));
  }

  if "my theories signed as *" exceptionToUser {
    S user = getUserName();
    if (empty(user)) ret "go to slack please";
    ret structure(getTheoriesSignedByAs(user, m.unq(0)));
  }

  if "theories signed by *" exceptionToUser {
    S user = m.unq(0);
    ret structure(getTheoriesSignedByAs(user, "default"));
  }
  
  if (match("theories page", s) || match("theories url", s))
    ret getBotURL();

  if (!master()) ret null;
  
  if "delete theory *" exceptionToUser {
    S name = m.unq(0);
    if (hasTheory(name)) {
      S text = getTheoryOpt(name);
      logMap("deleted", "name", name, "text", text, "time", now(), "signers", signMap.get(name));
      logMap("deleted", "name", name, "signers", signMap.get(name));
      theoriesRemove(name);
      
      signMap.remove(name);
      save("signMap");
      
      ret format("Theory * backed up & deleted", name);
    } else
      ret format("Theory * not found", name);
  }
  
  if "rename theory * to *" exceptionToUser {
    S name = m.unq(0), newName = m.unq(1);
    if (hasTheory(newName))
      ret format("A theory named * already exists", newName);
    if (hasTheory(name)) {
      S text = getTheoryOpt(name);
      theoriesPut(newName, text);
      theoriesRemove(name);

      // update signMap
      L<S> signers = signMap.get(name);
      signMap.addAll(newName, signers);
      signMap.remove(name);
      save("signMap");
      
      ret format("Theory * renamed to *", name, newName);
    } else
      ret format("Theory * not found", name);
  }
}

static S showTheories(L<S> theoryNames) {
  new StringBuilder buf;
  for (S name: theoryNames) {
    if (!hasTheory(name))
      buf.append(format("Theory * not found\n", name));
    else {
      buf.append(quote(name) + "\n" + slackSnippet(getTheoryOpt(name)) + "\n\n");
    }
  }
  ret str(buf).trim();
}

static S html(S uri, Map<S, S> params) {
  if (eq(uri, "/signList"))
    ret htmlencode(structure(signList));
  
  if (eq(uri, "/theories"))
    ret htmlencode(structure(theories));
    
  if (eq(uri, "/theoriesInc")) {
    int n = parseInt(or(params.get("n"), "0"));
    S id = params.get("id");
    
    if (nempty(id) && neq(id, theories.id()))
      n = 0;
      
    int m = (int) theories.file.length();
    S text = unnull(loadTextFileStartingFrom(theories.file, n));
    //text = substr(text, n);
    ret theories.id() + "\n" + m + "\n" + htmlencode(text);
  }

  boolean showMulti = false;
  new L data;
  MultiMap<S, Sign> signs = getSigningsByTheory();
  for (S name : getTheoryNames()) {
    S text = unnull(getTheoryOpt(name));
    boolean multi = false;
    Exception error = null;
    L<Sign> signings = signs.get(name);
    new L<S> bla;
    for (Sign sign : signings)
      bla.add(sign.user + " as " + sign.as);
    Map map = litmap(
      "Name", htmlencode(name),
      "Theory", pre(htmlencode(minitrim(rtrim(text)))),
      "Signed by", htmlencode(join(", ", bla)));
    if (showMulti) {
      map.put("Multiple rules?", multi);
      try {
        multi = nlIsMultipleStatements(text);
      } catch (Exception e) {
        error = e;
      }
    }
    if (error != null)
      map.put("Parse Error", str(error));
    data.add(map);
  }
  ret h3("Theories!") + htmlTable(data, false);
}

// preserves formatting of first line
static S minitrim(S s) {
  L<S> l = toLines(s);
  while (!empty(l) && empty(trim(first(l))))
    l.remove(0);
  ret autoUnindent(fromLines(l));
}

static S saveTheory(S name, S text, boolean autoModify) {
  boolean has = hasTheory(name);
  S oldText = getTheoryOpt(name);
  S origName = name;
  int counter = 0;
  while (has && !autoModify) {
    name = origName + "." + (char) (((int) 'a') + (++counter));
    has = hasTheory(name);
  }
  logMap(has ? "modified" : "added", "name", name, "text", text, "time", now(), "oldText", oldText);
  theoriesPut(name, text);
  ret format((has ? "OK, modified theory *" : "OK, added theory *"), name);
}

static synchronized long getTheoryCounter(S name) {
  S text = getTheoryOpt(name + ".count");
  ret isEmpty(text) ? 0 : parseLong(text);
}

// returns inc'ed value
static synchronized long incTheoryCounter(S name) {
  long c = getTheoryCounter(name);
  ++c;
  theoriesPut(name + ".count", str(c));
  ret c;
}

// returned list might include null elements
static L<S> getIncrements(S name) {
  new L<S> l;
  long n = getTheoryCounter(name);
  for (long i = 1; i <= n; i++)
    l.add(getTheoryOpt(name + "." + i));
  ret l;
}

static synchronized S incrementTheory(S name, S newText) {
  long n = incTheoryCounter(name);
  ret saveTheory(name + "." + n, newText, false);
}

static synchronized MultiMap<S, Sign> getSigningsByTheory() {
  new MultiMap<S, Sign> map;
  for (Sign s : signList)
    map.put(s.theory, s);
  ret map;
}

download  show line numbers  debug dex  old transpilations   

Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1002762
Snippet name: Theories Storing Bot (LIVE)
Eternal ID of this version: #1002762/1
Text MD5: f235db8b76b3e31ef4b3667e35e7c40d
Transpilation MD5: 141fc2f9712f7d8c8756b98e3aab8911
Author: stefan
Category: eleu / nl
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-03-24 19:55:37
Source code size: 9189 bytes / 328 lines
Pitched / IR pitched: No / No
Views / Downloads: 1011 / 2187
Referenced in: [show references]