!747 m { static L whiteList = litlist("#1001782", "#1001785", "#1001861"); static new Map bots; static long hitCount; p { readLocally("hitCount"); serveHttp(80); } static NanoHTTPD.Response serve(S uri, NanoHTTPD.Method method, Map header, Map parms, Map files) { print("Serving HTTP " + quote(uri)); ++hitCount; saveLocally("hitCount"); uri = dropPrefixMandatory("/", uri); if (eq(uri, "")) ret serveHomePage(); int i = uri.indexOf('/'); S firstPart = i >= 0 ? uri.substring(0, i) : uri; S rest = i >= 0 ? substr(uri, i) : "/"; // rest always starts with "/" ret serveBot(firstPart, rest); } static NanoHTTPD.Response serveBot(S botID, S subUri) { if (isSnippetID(botID)) { botID = formatSnippetID(botID); if (!containsSnippetID(whiteList, botID)) ret serve404("Bot not white listed: " + botID); if (eq(subUri, "reload")) { unloadBot(botID); ret serveHTML("OK, bot unloaded."); } //ret serveHTML("Calling bot: " + botID + " on: " + subUri); Class bot = loadBot(botID); S s = (S) callOpt(bot, "html", subUri); if (s == null) s = (S) callOpt(bot, "html"); if (s != null) ret serveHTML(s); } ret serve404(); } static NanoHTTPD.Response serveHomePage() { new StringBuilder buf; buf.append(""); buf.append("TinyBrain Bots"); buf.append(""); buf.append("

TinyBrain Bots

"); buf.append("
    "); for (S botID : whiteList) { botID = formatSnippetID(botID); boolean loaded = isBotLoaded(botID); S parsedID = "" + parseSnippetID(botID); buf.append("
  • " + botID + " ("); if (loaded) buf.append("loaded, "); buf.append("source)
  • "); } buf.append("
"); buf.append("

Hit count: " + hitCount + "

"); buf.append(""); buf.append(""); ret serveHTML(buf); } static synchronized Class loadBot(S botID) { botID = formatSnippetID(botID); Class c = bots.get(botID); if (c == null) { c = hotwire(botID); callMain(c); bots.put(botID, c); } ret c; } static synchronized void unloadBot(S botID) { botID = formatSnippetID(botID); // TODO: program clean-up bots.remove(botID); } static synchronized boolean isBotLoaded(S botID) { botID = formatSnippetID(botID); ret bots.containsKey(botID); } }