O serveOtherPage2(Req req) null { new Matches m; if (eq(req.uri, "/latestPost")) { UserPost post = highestConceptByField UserPost("created"); if (post == null) ret serve404("No posts in database"); ret servePost(post); } if (eq(req.uri, "/latestModifiedPost")) { UserPost post = highestConceptByField UserPost("_modified"); if (post == null) ret serve404("No posts in database"); ret servePost(post); } if (eq(req.uri, "/rootPosts")) { Cl posts = sortedByConceptIDDesc(filter(list(UserPost), post -> empty(post.postRefs))); framer().navBeforeTitle = true; framer().title = "Root Posts"; framer().add(ul(lmap postToHTMLWithDate(posts))); ret framer().render(); } if (eq(req.uri, "/allPosts")) { Cl posts = sortedByConceptIDDesc(list(UserPost)); framer().navBeforeTitle = true; framer().title = "All Posts"; framer().add(ul(lmap postToHTMLWithDate(posts))); ret framer().render(); } if (eq(req.uri, "/latestPosts")) { Cl posts = takeFirst(50, sortedByConceptIDDesc(list(UserPost))); framer().navBeforeTitle = true; framer().title = "Latest Posts & Replies"; framer().add(ul(lmap postToHTMLWithDate(posts))); ret framer().render(); } if (swic(req.uri, "/html/", m) && isInteger(m.rest())) { long id = parseLong(m.rest()); UserPost post = getConcept UserPost(id); if (post == null) ret serve404("Post not found"); ret post.text; } if (swic(req.uri, "/css/", m) && isInteger(m.rest())) { long id = parseLong(m.rest()); UserPost post = getConcept UserPost(id); if (post == null) ret serve404("Post not found"); ret serveWithContentType(post.text, "text/css"); } if (eq(req.uri, "/search")) { framer().navBeforeTitle = true; framer().title = "Search"; S q = trim(req.params.get("q")); framer().add(hform(hinputfield(+q) + " " + hsubmit("Search"))); framer().add(p(small("Search help: If you search for multiple words, they can appear in any order in the text. An underscore matches any character. Plus means space. Post titles, texts and types are searched."))); if (nempty(q)) { ScoredSearcher searcher = new(q); for (UserPost post) searcher.add(post, searcher.score(post.title)*3 + searcher.score(post.text)*2 + searcher.score(post.type)); L posts = searcher!; framer().add(p(b(addPlusToCount(searcher.maxResults, l(posts), nPosts(posts)) + " found for " + htmlEncode2(q)))); framer().add(ul(lmap postToHTMLWithDate(posts))); } ret framer().render(); } // serve replies for JSTree AJAX call if (eq(req.uri, "/jstree/replies")) { UserPost post = getConcept UserPost(parseLong(req.params.get("post"))); if (post == null) ret serveJSON(ll()); Cl refs = referencingPosts(post); /*[ { "id" : "demo_root_1", "text" : "Root 1", "children" : true, "type" : "root" }, { "id" : "demo_root_2", "text" : "Root 2", "type" : "root" } ]*/ ret serveJSON(map(refs, p -> litorderedmap( id := p.id, text := postToHTMLWithDate(post), children := nempty(referencingPosts(p)) ? true : null, type := "root" // ? ))); } if (startsWith(req.uri, "/bot/")) { S json = req.params.get("json"); new Map data; if (nempty(json)) data = jsonDecodeMap(json); data.putAll(withoutKey("json", req.params)); S userName = cast data.get("_user"); if (userName == null) ret serveJSON(error := "Need _user"); S botToken = cast data.get("_botToken"); if (botToken == null) ret serveJSON(error := "Need _botToken"); User user = conceptWhereIC User(name := userName); if (user == null) ret serveJSON(error := "User not found"); if (!eq(botToken, getVar(user.botToken))) ret serveJSON(error := "Wrong bot token"); S function = dropPrefix("/bot/", req.uri); if (eq(function, "authTest")) ret serveJSON(status := "You are authorized as " + user.name); if (eq(function, "postCount")) ret serveJSON(result := countConcepts(UserPost)); if (eq(function, "listPosts")) { LS fields = unnull(stringToStringListOpt tok_identifiersInOrder(data.get("fields"))); if (!fields.contains("id")) fields.add(0, "id"); ret serveJSON_breakAtLevels(2, result := map(list(UserPost), post -> mapToValues(fields, field -> cget(post, field)) )); } if (eq(function, "createPost")) { S text = cast data.get("text"); S type = cast data.get("type"); S title = cast data.get("title"); S botInfo = or2((S) data.get("botInfo"), "Made by bot"); new L postRefs; O _refs = data.get("refs"); if (_refs cast S) for (S s : tok_integersInOrder(_refs)) { UserPost ref = getConcept UserPost(parseLong(s)); if (ref == null) ret serveJSON(error := "Post " + s + " not found"); postRefs.add(ref); } if (empty(text) && empty(title)) ret serveJSON(error := "Need either a text or a title"); bool isPublic = eqOneOf(data.get("isPublic"), null, true, "1", "t", "true"); Pair post = uniq2 UserPost(creator := user, +text, +type, +title, +isPublic, +botInfo, +postRefs); ret serveJSON(status := post.b ? "Post created" : "Post existed already", postID := post.a.id); } ret serveJSON(error := "You are logged in correctly but function is unknown: " + function); } }