!7 cmodule GazelleWebServer > DynPrintLogAndEnabled { transient MyHTTPD server; void start() ctex { super.start(); if (!enabled) ret; dm_useLocalMechListCopies(); server = new MyHTTPD(80); server.serveFunction = func(S uri, SS parms) { serve(uri, parms) }; server.start(); print("HTTP server started on port " + server.getPort()); } void cleanMeUp { server.stop(); server = null; } O serve(S uri, SS params) { new Matches m; if (swic(uri, "/texts/", m)) { S textID = m.rest(); if (!possibleMD5(textID)) ret serve404(); ret serveTextFileAsUTF8(javaxDataDir("Gazelle Texts/" + textID)); } if (swic(uri, "/rule/", m)) { S ruleID = assertGlobalID(m.rest()); PairS textAndComment = unnull(dm_textAndCommentForRule(ruleID)); L feedback = dm_gazelle_feedbackForRule(ruleID); S title = "Rule " + ruleID; bool showStruct = eq("1", params.get('struct)); ret hhtml_head_title_body(title + " | Gazelle", heading(htmlEncode2(title)) + h3("Rule") + hpre(textAndComment.a) + (nempty(textAndComment.b) ? h3("Comments") + hpre(textAndComment.b) : "") + h3("Feedback") + htmlTable2(map(feedback, func(O o) -> Map { litorderedmap( "Judgement" := getString judgement(o), "Rewritten Rule" := getString_htmlEncode modifiedRule(o), "Generated Output" := getString_htmlEncode outText(o), "Mapping" := getString_htmlEncode varMap(o), "Context" := getString_htmlEncode context(o), "Comments" := hform( appendIfNempty(nlToBr(rtrim(getString_htmlEncode comments(o))), "
") + htextfield("comment_" + getString globalID(o))), "Struct" := showStruct ? getString matchedRuleStruct(o) : null) }), tdParams := litobjectarray(align := 'center, valign := 'top), htmlEncode := false)); } if (eq(uri, "/commands")) ret hhtml_head_title_body("Commands | Gazelle", linesLL(heading("Commands"), h3("!eval"), p([[You can evaluate Java code directly through Discord. Unless you are specifically authorized, only a ]] + ahref(rawSelfLink("safeIdentifiers"), "safe subset of identifiers") + " is allowed."), p("Example: " + tt("!eval 1+2")), p("In rare cases " + tt("!eval") + " may fail and you need to type " + tt("!real-eval") + " instead (which invokes an actual Java compiler)."))); if (eq(uri, "/safeIdentifiers")) ret hhtml_head_title_body("Safe Java Identifiers | Gazelle", linesLL( heading("Safe Java(X) identifiers for !eval"), hpre(lines(sortedIC(codeAnalysis_allSafeIdentifiers()))))); if (!eq(uri, "/")) ret serve404(); //final Map feedbackStats = dm_gazelle_feedbackStats(); final Map feedbackStats2 = dm_gazelle_feedbackStatsByJudgement(); // Home Page L> rules = dm_gazelle_allRulesWithComment("discord"); ret hhtml_head_title_body("Gazelle - Next-Gen Chat Bot", [[]] + hmobilefix() + hcenter( p(hsnippetimg(#1101500, height := 150, title := "Gazelle")) + p("Hello! I am a next-generation chat bot in training. " + targetBlank("https://BotCompany.de", "Maker.") + " " + targetBlank("https://slides.com/stefanreich/how-about-thinking-machines/", "Slides.") + " " + targetBlank("https://discordapp.com/invite/SEAjPqk", b("Join my Discord server!"))) + p(ahref(rawSelfLink("commands"), "Commands.")) + h3("Rules (" + l(rules) + ")") + htmlTable2(mapReversed(rules, func(T3 t) -> SS { S ruleID = t.c; ret litorderedmap( "Rule ID" := htmlEncode2(ruleID), "Rule Text" := htmlEncode_nlToBr(t.a), "Comments" := nlToBr( mapEachLine(withoutLine("discord", t.b), func(S s) -> S { new Matches m; if "use helper table mech list *" ret "use helper table mech list " + ahref(neatMechListURL($1), m.get(0)); ret s; })), "Feedback" := ahref(rawSelfLink("rule/" + ruleID), toInt(feedbackStats2.get(ruleID + "/good")) + " / " + toInt(feedbackStats2.get(ruleID + "/bad")))); }), htmlEncode := false, paramsByColName := litmap("Feedback" := litobjectarray(align := 'center)))), style := "font-family: Roboto"); } } sS rawSelfLink(S uri) { ret addSlashPrefix(uri); } sS heading(O contents) { ret h2(ahref(rawSelfLink(""), "Gazelle") + " | " + contents; }