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

605
LINES

< > BotCompany Repo | #1012254 // Stefan's Chat / Smart Bot's Chat [Include]

JavaX fragment (include)

1  
set flag NoNanoHTTPD.
2  
3  
static O stylesPost; // func(S) -> S
4  
5  
sS botFont = "Righteous"; //"Inconsolata"; //"Pacifico";
6  
sS botFontWeight = "normal";
7  
sS botImageID = #1101140; //#1008323;
8  
sbool bottomRight = false;
9  
sS templateID = bottomRight ? #1008787 : /*#1009000*/#1011983;
10  
static F0<S> headerHTML;
11  
sS heading = "BotCompany | Stefan's Chat";
12  
sbool forceHttps;
13  
sS roomName = "main"; // internal
14  
sS chatLineSymbol = "Chat line";
15  
static int maxMessages = 40;
16  
static int visitors;
17  
static int messageLimit = stefansChat_messageLimit();
18  
sbool postingDisabled = false;
19  
sbool showParses = true, notifications;
20  
static SS lastPosted = new ExpiringHashMap(2000); // ip -> message
21  
static volatile bool started;
22  
static O parserModule;
23  
24  
static int longPollTick = 100;
25  
static int longPollMaxWait = 1000*60;
26  
27  
static new L pagePostProcessors;
28  
29  
concept WeirdIPs {
30  
  Set<S> ips = setInConcept(this, new TreeSet);
31  
}
32  
33  
concept User {
34  
  S ipAddress, cookie;
35  
}
36  
37  
concept ByCookie {
38  
  S cookie;
39  
  S avatarID;
40  
}
41  
42  
sclass Msg {
43  
  S globalID = aGlobalIDUnlessLoading();
44  
  long time;
45  
  User user;
46  
  S text, parse;
47  
  Bool goodParse;
48  
  L<S> buttons;
49  
  bool botMark, auth;
50  
  int nr;
51  
  
52  
  *() {}
53  
  *(S ipAddress, S cookie, S *text) {
54  
    user = uniq_sync(User, +ipAddress, +cookie);
55  
    time = now();
56  
  }
57  
}
58  
59  
concept Conversation {
60  
  S cookie;
61  
  
62  
  // TODO: use synchro lists
63  
  new LL<Msg> oldDialogs;
64  
  new L<Msg> spam;
65  
  new L<Msg> msgs;
66  
  int counter;
67  
68  
  void add(Msg m) {
69  
    if (empty(oldDialogs)) oldDialogs.add(new L);
70  
    if (l(msgs) >= maxMessages)
71  
      listAdd(last(oldDialogs), popFirst(msgs));
72  
    listAdd(msgs, m);
73  
    change();
74  
    pcall { processMsgCommands(m); }
75  
  }
76  
  
77  
  // TODO
78  
  /*void correctSanity() {
79  
    if (empty(msgs)) ret;
80  
    int nr = last(msgs).nr;
81  
    int c = allCount();
82  
    while (nr > c) { msgs.add(Msg("null", "", "filler")); ++c; }
83  
    while (nr > c)
84  
  }*/
85  
  
86  
  void moveToSpam(Msg m, S toID) {
87  
    int i = msgs.indexOf(m);
88  
    if (i < 0) ret;
89  
    while (i < l(msgs) && neq(toID, msgs.get(i).globalID)) {
90  
      spam.add(msgs.get(i));
91  
      msgs.remove(i);
92  
      change();
93  
      if (empty(toID)) break;
94  
    }
95  
    moveMsgsUp();
96  
  }
97  
  
98  
  // move msgs from archive back to main dialog
99  
  void moveMsgsUp {
100  
    int delta = maxMessages-l(msgs);
101  
    print("moveMsgsUp delta=" + delta);
102  
    if (delta <= 0) ret;
103  
    L<Msg> old = last(oldDialogs);
104  
    if (old == null) ret;
105  
    L<Msg> l = takeLast(delta, old);
106  
    print("moveMsgsUp l=" + l(l));
107  
    if (empty(l)) ret;
108  
    synchronized(msgs) { msgs.addAll(0, l); }
109  
    removeLast(old, delta);
110  
    change();
111  
  }
112  
  
113  
  int allCount() { ret archiveSize() + l(msgs); }
114  
  int archiveSize() { ret lengthLevel2(oldDialogs) + l(spam); }
115  
}
116  
117  
svoid stefansChat_init {
118  
  loadPage_forcedTimeout = 20000;
119  
  dbIndexing(ByCookie, 'cookie);
120  
  started = true;
121  
  
122  
  for (Conversation conv)
123  
    print("room=" + conv.cookie + ": allCount=" + conv.allCount() + " old=" + l(conv.oldDialogs));
124  
    
125  
  L<Conversation> l = findConcepts(Conversation, cookie := roomName);
126  
  if (l(l) > 1) {
127  
    print("FIXING");
128  
    deleteConcept(smallestByMethod(l, 'allCount));
129  
  }
130  
}
131  
132  
html {
133  
 _registerThread();
134  
 while (!started) sleep(100);
135  
 
136  
 try {
137  
  S _vis = registerVisitor();
138  
  int visitorsToday = parseFirstInt(_vis);
139  
  main.visitors = visitorsToday;
140  
  //fS cookie = cookieSent();
141  
  
142  
  bool authed = webAuthed(params);
143  
  
144  
  print("uri=" + uri);
145  
  if (forceHttps && eq(uri, "/")) {
146  
    int port = subBot_currentPort();
147  
    print("Port=" + port);
148  
    if (port != 0 && port != 443)
149  
      ret hrefresh("https://" + domain());
150  
  }
151  
  
152  
  if (eq(uri, "/thoughts")) try {
153  
    loadPage_extraHeaders.set(litmap("X-Forwarded-For", clientIP()));
154  
    ret hrefresh(10) + loadPage(smartBotURL() + "/thoughts"
155  
      + (authed ? "?_pretendAuthed=1" : ""));
156  
  } catch e {
157  
    printShortException(e);
158  
    ret hrefresh(10) + hGoogleFontOswald() + hfullcenter("Bot loading...");
159  
  }
160  
    
161  
  new Matches mm;
162  
  Conversation conv;
163  
  {
164  
    lock dbLock();
165  
    
166  
    if (eq(uri, "/testauth")) ret "Authed: " + yn(authed);
167  
    
168  
    if (eq(uri, "/refresh")) {
169  
      if (!authed) ret "Not authed";
170  
      lock downloadLock();
171  
      parserModule = null;
172  
      ret "OK";
173  
    }
174  
      
175  
    if (swic(uri, "/setSmartBotURL/", mm)) {
176  
      if (!authed) ret "Not authed";
177  
      setSmartBotURL(urldecode(mm.rest()));
178  
      ret "OK";
179  
    }
180  
    
181  
    if (eq(uri, "/stats"))
182  
      ret "Threads: " + ul_htmlEncode(getThreadNames(registeredThreads()));
183  
      
184  
    if (eq(uri, "/spam"))
185  
      ret h3AndTitle("Spam Log") + ul(reversedList(map htmlencode(scanLog("spam.log"))));
186  
      
187  
    if (eq(uri, "/logs"))
188  
      ret withDBLock(func -> S {
189  
        int step = 100, n = toInt(params.get("n"));
190  
        L<Msg> msgs = reversed(allMsgs()); // TODO: optimize
191  
        new L<S> l;
192  
        int count = l(msgs);
193  
        msgs = subList(msgs, n, n+step);
194  
        for (Msg m : msgs)
195  
          l.add(formatMsgForLog(m) + "<br>");
196  
        ret h3_htitle("Chat Logs") 
197  
          + pageNav2("/logs", count, n, step, 'n)
198  
        + p(join(reversed(l)));
199  
      });
200  
    
201  
    conv = getConv(roomName);
202  
    
203  
    if (eq(uri, "/sanity")) {
204  
      if (conv == null) ret "No conv";
205  
      Msg m = last(conv.msgs);
206  
      int c = conv.allCount();
207  
      if (m == null) ret "Msgs: " + l(conv.msgs) + " vs " + c;
208  
      ret m.nr + " vs " + c;
209  
    }
210  
  
211  
    S weirdip = params.get("weirdip");
212  
    if (nempty(weirdip) && authed) {
213  
      uniq(WeirdIPs).ips.add(weirdip);
214  
      ret "OK";
215  
    }
216  
    
217  
    S inspam = params.get("inspam");
218  
    S to = params.get("to");
219  
    if (possibleGlobalID(inspam) && authed) {
220  
      Msg m = findWhere(conv.msgs, globalID := inspam);
221  
      if (m == null) ret "Msg not found";
222  
      conv.moveToSpam(m, to);
223  
      ret "OK, moved to spam";
224  
    }
225  
    
226  
    S rateParse = params.get("rateParse");
227  
    if (possibleGlobalID(rateParse) && authed) {
228  
      bool value = eq("1", params.get("ok"));
229  
      Msg m = findWhere(conv.msgs, globalID := rateParse);
230  
      if (m == null) ret "Msg not found";
231  
      m.goodParse = value;
232  
      change();
233  
      ret "OK, rated " + (value ? "good" : "bad");
234  
    }
235  
    
236  
    S reparse = params.get("reparse");
237  
    if (possibleGlobalID(reparse)) {
238  
      Msg m = findWhere(conv.msgs, globalID := reparse);
239  
      if (m == null) ret "Msg not found";
240  
      S parse = m.parse;
241  
      parseMsg(m);
242  
      bool change = neq(parse, m.parse);
243  
      if (change) {
244  
        m.goodParse = null;
245  
        change();
246  
      }
247  
      ret change ? htmlencode("OK -> " + m.parse) : "No change";
248  
    }
249  
    
250  
    if (eq(uri, "/parse-all") && authed) {
251  
      time { parseAll(); }
252  
      ret "OK, " + lastTiming() + " ms";
253  
    }
254  
255  
    S message = trim(params.get("btn"));
256  
    if (empty(message)) message = trim(params.get("message"));
257  
    bool botMark = nempty(params.get("botmark"));
258  
    //print("Have " + l(conv.msgs) + " msgs in conversation " + conv.cookie);
259  
    
260  
    if (match("clear", message)) {
261  
      print("Clearing.");
262  
      conv.oldDialogs.add(conv.msgs);
263  
      cset(conv, msgs := new L);
264  
      conv.change();
265  
      message = null;
266  
    }
267  
    
268  
    if (nempty(message) /*&& !lastUserMessageWas(conv, message)*/)
269  
      postMessage(conv, message, botMark, authed);
270  
  } // synchronized block
271  
  
272  
  if (eq(uri, "/msg")) ret "OK";
273  
  
274  
  if (eq(uri, "/n")) ret str(conv.allCount());
275  
  
276  
  if (eq(uri, "/lastmsg")) ret struct(msgsToJSON(takeLast(1, conv.msgs)));
277  
  
278  
  if (eq(uri, "/msgs-from-to")) {
279  
    int as = conv.archiveSize();
280  
    int a = parseInt(params.get('a))-as;
281  
    int b = parseInt(params.get('b))-as;
282  
    ret serveText(struct(msgsToJSON(subList(conv.msgs, a, b))));
283  
  }
284  
  
285  
  if (eq(uri, "/archive-from-to")) {
286  
    L<Msg> l = allMsgs();
287  
    int a = parseInt(params.get('a))-l(conv.spam);
288  
    int b = parseInt(params.get('b))-l(conv.spam);
289  
    ret serveText(struct(msgsToJSON(subList(l, a, b))));
290  
  }
291  
  
292  
  if (eq(uri, "/archive-regexp")) {
293  
    fS regexp = params.get("regexp");
294  
    fL<Msg> l = allMsgs();
295  
    ret serveText(struct(msgsToJSON(evalWithTimeoutOrNull(10.0, func -> L<Msg> {
296  
      Pattern pat = regexpIC(regexp);
297  
      new L<Msg> l2;
298  
      for (Msg m : l)
299  
        if (safeRegexpFind(pat, m.text))
300  
          l2.add(m);
301  
      ret l2;
302  
    }))));
303  
  }
304  
  
305  
  if (eq(uri, "/incremental")) {
306  
    if (uniq(WeirdIPs).ips.contains(clientIP())) {
307  
      print("Weird IP.");
308  
      sleepSeconds(10);
309  
    }
310  
    
311  
    int a = parseIntOpt(params.get("a"));
312  
    int vis = parseIntOpt(params.get("v"));
313  
    bool json = nempty(params.get('json)); // Funny thing is, JSON isn't even JSON. It's struct()
314  
315  
    long start = sysNow();
316  
    L msgs;
317  
    bool first = true;
318  
    while (licensed() && sysNow() < start+longPollMaxWait) {
319  
      int as = conv.archiveSize();
320  
      msgs = cloneSubList(conv.msgs, a-as);
321  
      //int visitors = main.visitors+random(2);
322  
      if (empty(msgs) && (vis == 0 || vis == visitors)) {
323  
        if (first) {
324  
          print("Long poll starting on " + roomName + ", " + a);
325  
          first = false;
326  
        }
327  
        sleep(longPollTick);
328  
      } else {
329  
        int ac = conv.allCount();
330  
        if (first) print("Long poll ended. a=" + a + ", as=" + as + ", msgs=" + l(msgs) + ", ac=" + ac);
331  
        if (json) ret struct/*jsonEncode*/(
332  
          litorderedmap(n := conv.allCount(),
333  
          msgs := msgsToJSON(msgs)));
334  
        new StringBuilder buf;
335  
        renderMessages(buf, msgs);
336  
        ret "<!-- " + ac + "-->\n"
337  
          + (vis == visitors ? "" : "<!-- vis " + visitors + " -->")
338  
          + buf;
339  
      }
340  
    }
341  
    ret "";
342  
  }
343  
  
344  
  lock dbLock();
345  
  
346  
  S html = loadSnippet_simpleCache(templateID);
347  
  S headerHTML = callF(main.headerHTML);
348  
  if (headerHTML != null)
349  
    html = replacePartBetweenStrings(html, "<!-- HEAD -->", "<!-- /HEAD -->", headerHTML);
350  
  new StringBuilder buf;
351  
  
352  
  print("Have " + n(conv.msgs, "msg"));
353  
  renderMessages(buf, conv.msgs);
354  
355  
  S styles = loadSnippet_simpleCache(#1010888);
356  
  styles = (S) callF_keepOnNull(stylesPost, styles);
357  
  html = html.replace("#BOTFONT#", botFont);
358  
  html = html.replace("#RELATIVESTYLES#", styles);
359  
  html = html.replace("#N#", str(conv.allCount()));
360  
  html = html.replace("#VISITORS#", str(visitorsToday));
361  
  html = html.replace("#INCREMENTALURL#", relativeRawBotLink(programID(), "incremental");
362  
  html = html.replace("#MSGURL#", rawBotLink_rel(programID(), "msg?message="));
363  
  
364  
  // debug mode
365  
  html = html.replace("var showActions = false;", "var showActions = true;");
366  
  
367  
  int yw = 150, yh = 100;
368  
  
369  
  // MAKE MORE
370  
  
371  
  S more =
372  
     hdiv([[<script language="JavaScript" type="text/javascript">
373  
TrustLogo("https://botcompany.de/images/1101147", "CL1", "none");
374  
</script>]], style := "float: right")
375  
//     + hsnippetimg(#1101147, width := 113, height := 59, style := "float: right")
376  
    + h3(hsnippetimg(#1009214, width := 389/2, height := 68/2, title := "BotCompany.de") + " &ndash; We make actual AI.")
377  
    + p(b(ahref("http://tinybrain.de/x30.jar", "The Software."))
378  
    + " (Windows/Linux/Mac OS.) Just double-click to run. " + targetBlank("http://java.com/", "Install Java if needed.") + "<br>"
379  
    + b(ahref("mailto:info@botcompany.de", "Mail to order a custom chat bot.")) + " "
380  
    + "Visitors today: " + span(visitorsToday, id := "visnum") + "." + "<br>"
381  
    + "Feel free to talk to " + targetBlank("http://smartbot.botcompany.de", b("Smart Bot")) + " in this chat!" + " - " + targetBlank("http://tinybrain.de/1010745", "Smart Bot's Source Code.") + " "
382  
    + targetBlank("http://javax.tinybrain.de/", "JavaX.") + " "
383  
    + targetBlank("http://tinybrain.de:8080/getraw.php?id=1012854&contentType=text/html", "Impressum.") + "<br>"
384  
    + htmlencode(unicode_rightPointingTriangle()) + " " + targetBlank("http://web-woody-lab.de/", "German smalltalk bot.") + " "
385  
    + htmlencode(unicode_rightPointingTriangle()) + " " + targetBlank("http://botcompany.de/1008316/raw", "Simple English product bot."))
386  
    + tag('table, tr(
387  
      td(youtubeEmbed("aPQ6Mfa6bEc", yw, yh))
388  
    + td(youtubeEmbed("7XCb89RJCcE", yw, yh), style := "padding-left: 10px")
389  
    + td(youtubeEmbed("AVqqn-lc_Ic", yw, yh), style := "padding-left: 10px")
390  
    + td(youtubeEmbed("aklRsg59NE8", yw, yh), style := "padding-left: 10px")
391  
    ))
392  
    + h3("Bot's Thoughts " + small("(Type " + tt("!word ...") + " to change)"))
393  
    + tag('iframe, "", src := relativeRawBotLink(programID(), "thoughts"), width:= 700, height := 300)
394  
  ;
395  
396  
  html = html.replace("$HEADING", htmlencode(heading) + " | " + targetBlank(selfLink("logs"), "Log"));
397  
  html = html.replace("<!-- MSGS HERE -->", str(buf));
398  
  html = html.replace("<!--MORE STUFF HERE-->", more);
399  
  html = hreplaceTitle(html, heading);
400  
  html = hmobilefix(html);
401  
  for (O f : pagePostProcessors) pcall { html = or((S) callF(f, html), html); }
402  
  ret html;
403  
 } finally {
404  
  _unregisterThread();
405  
 }
406  
}
407  
408  
svoid renderMessages(StringBuilder buf, L<Msg> msgs) {
409  
  for (Msg m : msgs) {
410  
    new Matches mm;
411  
    S html;
412  
    if (startsWith(m.text, "[IMAGE] ", mm)) {
413  
      // IMAGE POST
414  
      S url = trim(mm.get(0));
415  
      html = targetBlank(url, himg(url, width := 200, title := "User-submitted image", style := "display: block; margin-left: auto; margin-right: auto"));
416  
    } else {
417  
      // TEXT POST
418  
      //dynamize_linkParams.set(new O[] { target := "_blank" });
419  
      //html = dynamize(m.text);
420  
      html = html_linkURLs_targetBlank(htmlEncode_nlToBr_withIndents(m.text));
421  
    }
422  
    S name = "?";
423  
    if (m.user != null)
424  
      name = targetBlank("http://ai1.space/1008750/?ip=" + urlencode(m.user.ipAddress), m.user.ipAddress, style := "color: white", title := "User's IP Address") + (nempty(m.user.cookie) ? " / " + targetBlank("http://ai1.space/" + m.user.cookie, m.user.cookie, style := "color: white", title := "User's Cookie") : "")
425  
        + " | " + targetBlank(/*"http://ai1.space/" + m.globalID*/encyclopediaLink(chatLineSymbol + " " + m.nr),
426  
          /*m.globalID*/m.nr, style := "color: white", title := "Message ID");
427  
    S parse = html_linkURLs_targetBlank(htmlEncode_nlToBr_withIndents(unnull(m.parse)));
428  
    if (webAuthed()) {
429  
      name += " " + targetBlank(relativeBotLink(programID()) + "?inspam=" + m.globalID, "[spam]");
430  
      if (!m.botMark) {
431  
        name += " " + targetBlank(relativeBotLink(programID()) + "?rateParse=" + m.globalID + "&ok=1", "[gp]");
432  
        name += " " + targetBlank(relativeBotLink(programID()) + "?rateParse=" + m.globalID + "&ok=0", "[bp]");
433  
        name += " " + targetBlank(relativeBotLink(programID()) + "?reparse=" + m.globalID, "[rp]");
434  
      }
435  
    }
436  
    renderMessage(buf, name, formatTime(m.time), html, m.globalID, m.user == null ? null : m.user.cookie, m.botMark, m.nr, parse, m.goodParse);
437  
  }
438  
      
439  
  if (empty(msgs)) ret;
440  
  L<S> buttons = last(msgs).buttons;
441  
  if (nempty(buttons))
442  
    appendButtons(buf, buttons);
443  
}
444  
445  
static O msgsToJSON(L<Msg> msgs) {
446  
  ret map(msgs, func(Msg m) { litorderedmap(
447  
    time := m.time,
448  
    text := m.text,
449  
    ip := m.user.ipAddress,
450  
    cookie := m.user.cookie,
451  
    buttons := m.buttons,
452  
    auth := trueOrNull(m.auth),
453  
    botMark := trueOrNull(m.botMark),
454  
    nr := m.nr,
455  
    globalID := m.globalID
456  
  ) });
457  
}
458  
459  
svoid renderMessage(StringBuilder buf, S name, S time, S html, S id, S cookie, bool botMark, int nr, S parse, Bool goodParse) {
460  
  ByCookie bc = findConcept(ByCookie, +cookie);
461  
  S imgID = botMark ? botImageID : #1008359;
462  
  if (nempty(cookie) && !botMark /*XXX*/ && bc != null) imgID = or(bc.avatarID, imgID);
463  
  S imgLink = snippetImgLink(imgID);
464  
  //if (nempty(id)) buf.append(hcomment("Msg ID: " + id));
465  
466  
  if (botMark) parse = null;
467  
  if (nempty(parse))  
468  
    parse = [[<p style="background: white; margin: 0; padding: 0; text-align: right; color: ]] + (isTrue(goodParse) ? "green" : isFalse(goodParse) ? "red" : "#888") + [[;"><small>]] + parse + [[</small>]];
469  
  
470  
	buf.append([[<div class="direct-chat-msg doted-border" id="msg_#ID#">
471  
    <div class="direct-chat-info clearfix">
472  
    <span class="direct-chat-name pull-left">$NAME</span>
473  
    </div>
474  
    <img alt="message user image" src="$IMG" class="direct-chat-img">
475  
    <div class="direct-chat-text" $STYLE>
476  
      <!-- TEXT --><TEXT /><!-- END TEXT -->
477  
      <PARSE />
478  
    </div>
479  
    <div class="direct-chat-info clearfix">
480  
      <span class="direct-chat-timestamp pull-right">$TIME</span>
481  
    </div>
482  
  </div>
483  
    ]].replace("$IMG", imgLink)
484  
      .replace("$NAME", name)
485  
      .replace("$TIME", time)
486  
      .replace("#ID#", id)
487  
      .replace("$STYLE", botMark
488  
        //? "style='text-align: right'"
489  
        //? "style='font-style: italic'"
490  
        ? "style='font-family: " + botFont + "; font-weight: " + botFontWeight + "'"
491  
        : "")
492  
      .replace("<PARSE />", unnull(parse))
493  
      .replace("<TEXT />", html));
494  
}
495  
496  
svoid appendButtons(StringBuilder buf, L<S> buttons) {
497  
  S buttonsHtml = lines(map(buttons, func(S text) {
498  
    hsubmit(text, name := "btn")
499  
  }));
500  
	buf.append([[<div class="direct-chat-msg doted-border">
501  
    <div class="direct-chat-buttons">
502  
      $BUTTONS
503  
    </div>
504  
  </div>
505  
    ]].replace("$BUTTONS", buttonsHtml);
506  
}
507  
508  
svoid appendDate(StringBuilder buf, S date) {
509  
  buf.append([[
510  
  <div class="chat-box-single-line">
511  
		<abbr class="timestamp">DATE</abbr>
512  
	</div>]].replace("DATE", date));
513  
}
514  
515  
sS formatTime(long time) {
516  
  ret formatGMTWithOptionalDate_24(time);
517  
}
518  
519  
sS formatMsgForLog(Msg m) {
520  
  ret htmlencode(m.nr + " " + formatDateAndTime(m.time)) + " - " + htmlencode(m.user.ipAddress + ": " + m.text);
521  
}
522  
523  
static Conversation getConv(fS cookie) {
524  
  ret uniq_sync(Conversation, +cookie);
525  
}
526  
527  
static L<Msg> allMsgs() {
528  
  new L<Msg> l;
529  
  for (Conversation c) {
530  
    for (L<Msg> msgs : cloneList(c.oldDialogs)) addAll(l, msgs);
531  
    addAll(l, c.msgs);
532  
  }
533  
  ret l;
534  
}
535  
536  
svoid processMsgCommands(Msg msg) {
537  
  new Matches m;
538  
  if (swic(msg.text, "avatar ", m)) {
539  
    S avatarID = fsI(trim($1));
540  
    BufferedImage img = loadImage2(avatarID);
541  
    if (img.getWidth() <= 400 && img.getHeight() <= 400)
542  
      cset(uniq(ByCookie, cookie := msg.user.cookie), +avatarID);
543  
    else fail("Avatar too big: " + avatarID);
544  
  }
545  
}
546  
547  
svoid postMessage(Conversation conv, S message, bool botMark, bool authed) {
548  
  message = shorten(message, messageLimit, " [...]");
549  
  S ip = clientIP();
550  
  print("Have message from " + ip + " at " + gmtWithSeconds() + " in thread " + currentThread() + ": " + quote(shorten(message, 80)));
551  
  
552  
  if (startsWith(ip, "66.249.65."))
553  
    if (matchOneOf(message, "web * is invalid", "web * is correct"))
554  
      ret;
555  
  
556  
  // anti hammer mechanism
557  
  S key = ip + " " + botMark;
558  
  if (eq(lastPosted.get(key), message)) {
559  
    print("Skipping same.");
560  
    ret;
561  
  }
562  
  
563  
  lastPosted.put(key, message);
564  
    
565  
  if (postingDisabled) ret;
566  
  
567  
  if (!botMark && !authed && superSimpleSpamTester(message)) {
568  
    print(logStructureWithDate("spam.log", "Ignoring spam message: " + quote(message)));
569  
    ret;
570  
  }
571  
  
572  
  // ADD NOT SPAM MESSAGE
573  
  Msg msg = new Msg(clientIP(), cookieConcept(), message);
574  
  msg.botMark = botMark;
575  
  msg.auth = authed;
576  
  //msg.nr = toInt(getOpt(last(conv.msgs), 'nr))+1;
577  
  if (conv.counter == 0) cset(conv, counter := conv.allCount());
578  
  cset(conv, counter := conv.counter+1);
579  
  msg.nr = conv.counter;
580  
  parseMsg(msg);
581  
  
582  
  conv.add(msg);
583  
  print("Have " + l(conv.msgs) + " msgs in conversation " + conv.cookie + " after add");
584  
}
585  
586  
svoid parseAll {
587  
  for (Msg m : allMsgs()) {
588  
    m.parse = null;
589  
    parseMsg(m);
590  
  }
591  
  change();
592  
}
593  
594  
svoid parseMsg(Msg msg) {
595  
  {
596  
    if (!showParses) ret;
597  
    lock downloadLock();
598  
    if (parserModule == null)
599  
      parserModule = hotwire(#1012396);
600  
  }
601  
  pcall {
602  
    if (countLines(msg.text) > 1) msg.parse = null;
603  
    else msg.parse = (S) callOpt(parserModule, 'ai_tripelizeAndRenderTriple, msg.text);
604  
  }
605  
}

Author comment

Began life as a copy of #1008998

download  show line numbers  debug dex  old transpilations   

Travelled to 15 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1012254
Snippet name: Stefan's Chat / Smart Bot's Chat [Include]
Eternal ID of this version: #1012254/76
Text MD5: 1b70f3109781596b1244d164293888fe
Author: stefan
Category: javax / a.i.
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2018-08-05 16:14:10
Source code size: 20085 bytes / 605 lines
Pitched / IR pitched: No / No
Views / Downloads: 635 / 1137
Version history: 75 change(s)
Referenced in: [show references]