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

409
LINES

< > BotCompany Repo | #1021960 // Gazelle Web Server backup

JavaX source code (Dynamic Module) - run with: Stefan's OS

1  
!7
2  
3  
cmodule GazelleWebServer > DynPrintLogAndEnabled {
4  
  transient MyHTTPD server;
5  
  new Set<S> authedCookies;
6  
  transient new GazelleContextCache contextCache;
7  
  
8  
  transient new ThreadLocal<O[]> bodyParams;
9  
  transient new ThreadLocal<Bool> authed;
10  
11  
  int absoluteMaxResults = 1000, defaultMaxResults = 100;
12  
13  
  void start() ctex {
14  
    super.start();
15  
    if (!enabled) ret;
16  
    
17  
    dm_useLocalMechListCopies();
18  
    
19  
    server = new MyHTTPD(80);
20  
    server.serveFunction = func(S uri, SS parms) {
21  
      serve(uri, parms)
22  
    };
23  
    server.start();
24  
    print("HTTP server started on port " + server.getPort());
25  
  }
26  
  
27  
  void cleanMeUp {
28  
    server.stop();
29  
    server = null;
30  
  }
31  
  
32  
  O serve(S uri, SS params) enter {
33  
    new Matches m;
34  
    
35  
    S cookie = serveHttp_cookieHandling();
36  
    bool authed = nempty(cookie) && syncContains(authedCookies, cookie);
37  
    temp tempSetTL(this.authed, authed);
38  
    print("Cookie: " + cookie + ", authed: " + authed);
39  
    S master = trim(loadTextFile(javaxSecretDir("gazelle-master-pw")));
40  
    S attempt = params.get('_pass);
41  
    if (nempty(attempt) && nempty(cookie) && nempty(master)) {
42  
      if (eq(attempt, master)) {
43  
        print("Login SUCCEEDED");
44  
        syncAdd(authedCookies, cookie);
45  
        change();
46  
        authed = true;
47  
      } else
48  
        print("Login FAILED");
49  
    }
50  
    
51  
    if (eq(uri, "/favicon.ico"))
52  
      ret serveFile(loadLibrary(#1400189), faviconMimeType());
53  
      
54  
    O[] bodyParams = litobjectarray(style := "font-family: Roboto Mono; " + (authed ? "background-color: #FFFF88" : ""));
55  
    temp tempSetTL(this.bodyParams, bodyParams);
56  
    
57  
    if (eq(uri, "/login"))
58  
      ret hhtml_head_title_body("Login" + " | Gazelle",
59  
        hprelude() +
60  
          (nempty(master) ? hpostform(hpasswordfield('_pass)) : "No master PW"), bodyParams);
61  
    
62  
    if (swic(uri, "/texts/", m)) {
63  
      S textID = m.rest();
64  
      if (!possibleMD5(textID)) ret serve404();
65  
      ret serveTextFileAsUTF8(javaxDataDir("Gazelle Texts/" + textID));
66  
    }
67  
    
68  
    if (eq(uri, "/lastOutput")) {
69  
      L<GazelleLine> lines = reversed(takeLast(10, dm_discord_allBotLines()));
70  
      ret hframe("Last Output", hcenter(hheading("Last Output")
71  
        + htmlTable2(
72  
          map(lines, line -> {
73  
            L applications = dm_gazelle_applicationsForMsgID(line.msgID);
74  
            //print("Got " + n2(applications, "application") + " for " + line.msgID + " from " + dm_gazelle_longFeedbackCRUD());
75  
            ret litorderedmap(
76  
              "Date" := spanTitle("Message ID: " + line.msgID, htmlencode2(localDateWithMinutes(line.timestamp))),
77  
              "Gazelle said:" := htmlencode2(line.text),
78  
              "Applied rules" := joinWithSpace(map(f<S, S> ruleLink, collect ruleID(applications)))
79  
            );
80  
          }), htmlEncode := false, tableParams := litparams(cellpadding := 5))
81  
      ));
82  
    }
83  
      
84  
    if (eq(uri, "/lastInput")) {
85  
      L<GazelleLine> lines = reversed(takeLast(30, dm_discord_allLines()));
86  
      ret hframe("Last Input", hcenter(hheading("Last Input")
87  
        + htmlTable2(
88  
          map(lines, line -> {
89  
            //L applications = dm_gazelle_applicationsForMsgID(line.msgID);
90  
            ret litorderedmap(
91  
              "Date" := spanTitle("Message ID: " + line.msgID, htmlencode2(localDateWithMinutes(line.timestamp))),
92  
              "Author" := htmlencode(line.user),
93  
              "Bot?" := htmlencode(line.bot ? "yes" : ""),
94  
              "Line" := htmlencode2(line.text),
95  
              //"Applied rules" := joinWithSpace(map(f<S, S> ruleLink, collect ruleID(applications))),
96  
              "More" := moreForMsgID(line.msgID)
97  
            );
98  
          }), htmlEncode := false, tableParams := litparams(cellpadding := 5))
99  
      ));
100  
    }
101  
    
102  
    if (swic(uri, "/revisit/", m)) {
103  
      long msgID = assertNotZero(parseLong(m.rest()));
104  
      GazelleLine line = dm_discord_lineForMsgID(msgID);
105  
      if (line == null) ret "Message not found: " + msgID;
106  
      long startTime = sysNow();
107  
      L<GazelleTree> tree = dm_gazelle_revisitChatLine(msgID,
108  
        ctx := contextCache!);
109  
      long endTime = sysNow();
110  
      
111  
      //print("Tree to string.");
112  
      S tv = treeViewToString_withoutHijackPrint(gazelle_treeView(tree),
113  
        stringifier := func(TreeView<GazelleTree> t) -> S { gazelleTreeToHTML(t.node()) });
114  
      //print("children=" + l(tree) + ", tv = " + quote(tv));
115  
      ret hframe("Revisiting msg " + msgID,
116  
        hheading("Revisiting message " + msgID + ": " + htmlEncode2(line.text))
117  
        + nlToBr_withIndents(tv)
118  
        + p((endTime-startTime) + " ms"));
119  
    }
120  
    
121  
    Request request = new(authed, params);
122  
      
123  
    if (swic(uri, "/rule/", m)) {
124  
      S ruleID = assertGlobalID(m.rest());
125  
      ret request.serveRule(ruleID, params);
126  
    }
127  
    
128  
    if (eq(uri, "/search"))
129  
      ret search(params);
130  
    
131  
    if (eq(uri, "/wikipedia"))
132  
      ret request.serveWikipedia();
133  
    
134  
    if (eq(uri, "/commands"))
135  
      ret hhtml_head_title_body("Commands | Gazelle",
136  
        hprelude() +
137  
        linesLL(hheading("Commands"),
138  
          h3("!eval"),
139  
        
140  
          p([[You can evaluate Java code directly through Discord.
141  
          Unless you are specifically authorized, only a ]] + ahref(rawSelfLink("safeIdentifiers"), "safe subset of identifiers") + " is allowed."),
142  
          
143  
          p("Example: " + tt("!eval 1+2")),
144  
          p("In rare cases " + tt("!eval") + " may fail and you need to type " + tt("!real-eval") + " instead (which invokes an actual Java compiler).")), bodyParams);
145  
146  
    if (eq(uri, "/safeIdentifiers"))
147  
      ret hhtml_head_title_body("Safe Java Identifiers | Gazelle",
148  
        hprelude() +
149  
        linesLL(
150  
          hheading("Safe Java(X) identifiers for !eval"),
151  
          hpre(lines(sortedIC(codeAnalysis_allSafeIdentifiers())))), bodyParams);
152  
          
153  
    if (!eq(uri, "/"))
154  
      ret serve404();
155  
    
156  
    //final Map<S, Int> feedbackStats = dm_gazelle_feedbackStats();
157  
    final Map<S, Int> feedbackStats2 = dm_gazelle_feedbackStatsByJudgement();
158  
    final Map<S, Int> feedbackStats3 = dm_gazelle_feedbackStatsForNonJudged();
159  
    
160  
    // Home Page / Main List
161  
    
162  
    L<T3<S>> rules = dm_allRulesFromRulesModuleWithCommentsAndIDs();
163  
      // dm_gazelle_allRulesWithComment("discord");
164  
      
165  
    bool showAll = eq("1", params.get('showAll));
166  
      
167  
    L<Map> mapped = mapReversed(rules,
168  
      func(T3<S> t) -> SS {
169  
        S ruleID = t.c;
170  
        ret litorderedmap(
171  
          "Rule ID" := !showAll ? null : htmlEncode2(ruleID),
172  
          "Rule Text" := htmlEncode_nlToBr(t.a),
173  
          "Comments" := !showAll ? null : nlToBr(
174  
            mapEachLine(/*withoutLine("discord",*/ t.b/*)*/, func(S s) -> S {
175  
              new Matches m;
176  
              if "use helper table mech list *"
177  
                ret "use helper table mech list " +
178  
                  ahref(neatMechListURL($1), m.get(0));
179  
              ret s;
180  
            })),
181  
          "# of applications" := strOr(feedbackStats3.get(ruleID), "-"),
182  
          "Feedback" := ahref(rawSelfLink("rule/" + ruleID),
183  
            "+" + toInt(feedbackStats2.get(ruleID + "/good"))
184  
              /*+ " / " +
185  
            toInt(feedbackStats3.get(ruleID))*/
186  
              + " / " + 
187  
            "-" + toInt(feedbackStats2.get(ruleID + "/bad"))));
188  
      });
189  
    
190  
    S sortBy = params.get('sortBy);
191  
    bool desc = eq("1", params.get('desc));
192  
    if (nempty(sortBy))
193  
      if (eq(sortBy, "Feedback"))
194  
        mapped = sortByCalculatedField(mapped, func(Map map) -> Int {
195  
          S s = cast map.get("Feedback");
196  
          ret parseFirstInt(s) - parseSecondInt(s);
197  
        });
198  
      else if (eq(sortBy, "# of applications"))
199  
        mapped = sortByMapKeyAlphaNum(mapped, sortBy);
200  
      else
201  
        mapped = sortByMapKey(mapped, sortBy);
202  
    if (desc) reverseInPlace(mapped);
203  
      
204  
    ret hhtml_head_title_body("Gazelle - Next-Gen Chat Bot",
205  
      hprelude() +
206  
      hopeningTag link(rel :="icon", href := "/favicon.ico?v=2") +
207  
      hcenter(
208  
        p(b("GAZELLE 2019", style := "font-size: 5em")) +
209  
        p(hsnippetimg(#1101500, height := 150, title := "Gazelle")) +
210  
        p(span("<b>Hello! I am a next-generation chat bot in training.</b>", style := "font-size: 1.4em") + "<br>"
211  
          + span(targetBlank("https://BotCompany.de", "Maker.") + " "
212  
          + targetBlank("https://slides.com/stefanreich/how-about-thinking-machines/", "Slides.") + " "
213  
          + targetBlank("https://discordapp.com/invite/SEAjPqk", b("Join my Discord server!")), style := "font-size: 1.2em"))
214  
        + hform(p(ahref(rawSelfLink("commands"), "Commands.")
215  
        + " " + ahref(rawSelfLink("lastOutput"), "Last output.")
216  
        //+ " " + ahref(rawSelfLink("search"), "Search.")
217  
        + " | " + hinputfield('q, style := "width: 120px") + " " + hsubmit("Search")), action := "/search")
218  
        
219  
        + h3("Rules (" + l(rules) + ")")
220  
      + htmlTable2(mapped,
221  
          htmlEncode := false,
222  
          paramsByColName := litmap(
223  
            "Feedback" := litobjectarray(align := 'center),
224  
            "# of applications" := litobjectarray(align := 'center)),
225  
          replaceHeaders := litmap(
226  
            "Rule Text" := "Rule (input + more input => output)",
227  
            "# of applications" := sortLink(params, "# of applications"),
228  
            "Feedback" := sortLink(params, "Feedback")),
229  
          tdParams := litobjectarray(valign := 'top)
230  
          )
231  
          + p(ahref(hqueryWithoutNanoHTTPDStuff(mapPlus(params, showAll := 1)), "Show technical stuff"))
232  
          ), bodyParams);
233  
  }
234  
  
235  
  S hframe(S title, O body) {
236  
    print("Params: " + sfu(bodyParams!));
237  
    ret hhtml_head_title_body(title + " | Gazelle",
238  
      hprelude() +
239  
      body,
240  
      bodyParams!);
241  
  }
242  
  
243  
  S ruleLink(S ruleID) {
244  
    if (!isGlobalID(ruleID)) ret htmlEncode2(ruleID);
245  
    ret ahref("/rule/" + ruleID, ruleID);
246  
  }
247  
  
248  
  S gazelleTreeToHTML(GazelleTree tree) {
249  
    if (tree == null) ret "*";
250  
    ret (tree.isSplitNode ? "[split] " : "")
251  
      + htmlEncode2(tree.line) + appendSquareBracketed(
252  
      joinWithComma(listPlus(
253  
        map htmlEncode2(tree.renderQualityElements()),
254  
        ruleLink(tree.ruleID()))));
255  
  }
256  
  
257  
  S moreForMsgID(long msgID) {
258  
    ret ahref(rawSelfLink("revisit/" + msgID), "revisit", rel := "nofollow");
259  
  }
260  
  
261  
  S search(SS params) {
262  
    S q = trim(params.get('q));
263  
    Set<S> types = singletonCISetIfNempty(params.get('type));
264  
    int maxResults = min(absoluteMaxResults, toIntOr(params.get('max), defaultMaxResults));
265  
    L results = empty(q) ? null : dm_gazelle_fullSearch(q, +types, maxResults := maxResults+1);
266  
    S title = empty(q) ? "Search" : "Search results for: " + q;
267  
    ret hframe(title,
268  
      hheading(htmlEncode2(title)) +
269  
      hform("Terms: " + hinputfield('q, value := q, autofocus := true)
270  
        + " Type: " + hselect_list(ll("", "Rules", "Lines"), params.get('type), name := 'type)
271  
        + " " + hsubmit("Search"), action := "/search") +
272  
      (empty(results) ?
273  
        (empty(q) ? "" : "No results") : p(
274  
          l(results) > maxResults ? maxResults + "+ results" : n2(results, "result"))
275  
          + htmlTable2(map(takeFirst_lazy(maxResults, results), o -> {
276  
        S type = shortClassName(o);
277  
        bool isLine = eq(type, "Line");
278  
        long msgID = isLine ? getLong msgID(o) : 0;
279  
        Map map = litorderedmap("Type" :=
280  
          isLine ? spanTitle("Message ID: " + msgID, type) : type);
281  
        S text = htmlEncode2OrNull(getStringOpt text(o));
282  
        if (isLine)
283  
 {
284  
          map.put("Date" := localDateWithMinutes(getLong created(o)));
285  
          map.put("By" := (S) call(o, 'userName));
286  
        }
287  
        if (text != null) {
288  
          if (eq(type, "Rule"))
289  
            text = ahref("/rule/" + getString globalID(o), text);
290  
          mapPut(map, "Text", text);
291  
        }
292  
        if (isLine)
293  
          map.put("More" := moreForMsgID(msgID));
294  
        ret map;
295  
      }), htmlEncode := false)));
296  
    }
297  
298  
  class Request {
299  
    bool authed;
300  
    SS params;
301  
    
302  
    *(bool *authed, SS *params) {}
303  
  
304  
    S serveRule(S ruleID, SS params) {
305  
      // add rule comment
306  
      S comment = trim(params.get("comment"));
307  
      if (nempty(comment)) {
308  
        if (!authed) comment = "[anon] " + comment;
309  
        dm_gazelle_addRuleComments_verbose(ruleID, ll(comment));
310  
      }
311  
  
312  
      PairS textAndComment = unnull(dm_textAndCommentForRule(ruleID));
313  
      L feedback = dm_gazelle_feedbackForRule(ruleID);
314  
      L applications = dm_gazelle_applicationsForRule(ruleID);
315  
      Map<S, O> feedbackByContext = indexByFieldNotNull context(feedback);
316  
      S title = "Rule " + ruleID;
317  
      bool showStruct = eq("1", params.get('struct));
318  
      L list = cloneList(feedback);
319  
      for (O o : applications)
320  
        if (!containsKey(feedbackByContext, getString context(o)))
321  
          list.add(o);
322  
          
323  
      // add feedback comments
324  
      
325  
      for (S applicationID, S text : subMapStartingWith_dropPrefix(params, "comment_")) {
326  
        continue if empty(text = trim(text));
327  
        if (!authed) text = "[anon] " + text;
328  
        O app = findByField(list, globalID := applicationID);
329  
        print("Processing comment for " + applicationID + " - " + app);
330  
        if (app == null) continue;
331  
        Set<S> comments = asSet(tlft(getString comments(app)));
332  
        if (!contains(comments, text))
333  
          call(app, '_setField, comments := appendWithNewLine(getString comments(app), text));
334  
      }
335  
      
336  
      // Serve Rule & Applications & Feedback
337  
      
338  
      L<Map> mapped = map(list, func(O o) -> Map {
339  
        litorderedmap(
340  
          "Judgement" := getString judgement(o),
341  
          "Rewritten Rule" := getString_htmlEncode modifiedRule(o),
342  
          "Generated Output" := getString_htmlEncode outText(o),
343  
          "Mapping" := dropPrefix("cimap", getString_htmlEncode varMap(o)),
344  
          "Context" := getString_htmlEncode context(o),
345  
          "Comments" := hform(
346  
            appendIfNempty(nlToBr(rtrim(getString_htmlEncode comments(o))), "<br>")
347  
            + htextfield("comment_" + getString globalID(o))),
348  
          "Struct" := showStruct ? getString matchedRuleStruct(o) : null)
349  
      });
350  
      
351  
      S sortBy = params.get('sortBy);
352  
      if (nempty(sortBy))
353  
        mapped = sortByMapKey(mapped, sortBy);
354  
        
355  
      Collection<S> statements = dm_gazelle_statementsForRule(ruleID);
356  
  
357  
      ret hhtml_head_title_body(title + " | Gazelle",
358  
        hprelude() +
359  
        hheading(htmlEncode2(title))
360  
        + h3("Rule")
361  
        + hblock(textAndComment.a)
362  
        + (nempty(textAndComment.b) ? h3("Comments") + hblock(textAndComment.b) : "")
363  
        + "<br><br>" + hform(
364  
            "Add comment: " + htextfield("comment"))
365  
        + h3("Feedback")
366  
        + htmlTable2(mapped, tdParams := litobjectarray(align := 'center, valign := 'top), htmlEncode := false)
367  
        + h3("Analysis 1")
368  
        + hblock(lines(statements))
369  
        + h3("Analysis 2")
370  
        + hblock(sfuLines(objectToMap(
371  
          ai_gazelle_analyzeStatementsForRule(statements))))
372  
        , bodyParams!);
373  
    }
374  
    
375  
    S serveWikipedia() {
376  
      /*hheading("All Simple English Wikipedia Topics")
377  
        + htmlTable2(map(simpleWikipediaTopics_cached(), topic -> litorderedmap("Topic" := topic))));*/
378  
      ret hframe("Wikipedia",
379  
        hheading("Retrieved Simple Wikipedia Pages")
380  
        + htmlTable2(map(simpleWikipedia_allCachedTopics(), topic -> litorderedmap("Topic" := topic))));
381  
382  
    }
383  
    
384  
  } // end of Request
385  
386  
} // end of class
387  
388  
sS rawSelfLink(S uri) { ret addSlashPrefix(uri); }
389  
390  
sS hheading(O contents) {
391  
  ret h2(ahref(rawSelfLink(""), "Gazelle") + " | " + contents);
392  
}
393  
394  
sS hprelude() {
395  
  ret [[<link href="https://fonts.googleapis.com/css?family=Roboto+Mono" rel="stylesheet">]] +
396  
    hmobilefix();
397  
}
398  
399  
sS hblock(S s) {
400  
  ret htmlEncode_nlToBr(s);
401  
}
402  
403  
sS sortLink(SS params, S key) {
404  
  params = cloneMap(params);
405  
  mapPutOrRemove(params, 'desc,
406  
    eq(params.get('sortBy), key) && !eq("1", params.get('desc)) ? "1" : null);
407  
  params.put(sortBy := key);
408  
  ret ahref(hqueryWithoutNanoHTTPDStuff(params), htmlEncode2(key));
409  
}

Author comment

Began life as a copy of #1021679

download  show line numbers  debug dex  old transpilations   

Travelled to 7 computer(s): bhatertpkbcr, cfunsshuasjs, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1021960
Snippet name: Gazelle Web Server backup
Eternal ID of this version: #1021960/1
Text MD5: 3a22e640d7ec1bf2341e23b5eaf22333
Author: stefan
Category: javax / stefan's os / a.i. / web
Type: JavaX source code (Dynamic Module)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2019-03-04 10:40:41
Source code size: 16350 bytes / 409 lines
Pitched / IR pitched: No / No
Views / Downloads: 213 / 221
Referenced in: [show references]