!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 Mono");
}
}
sS rawSelfLink(S uri) { ret addSlashPrefix(uri); }
sS heading(O contents) {
ret h2(ahref(rawSelfLink(""), "Gazelle") + " | " + contents;
}