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

303
LINES

< > BotCompany Repo | #1002900 // Web Chat API (include)

JavaX fragment (include)

static S myBotName;
static long botRoom = 1;
static new Matches m; // for matching lines
static int historyGrab = 10; // read last 10 lines from history
static new L<ChatLine> msgs;
static long lastSucked; // timestamp
static long suckDelay = 2000; // suck every X ms
static int maxLineLength = 1024; // should match groupchat.json.botsay.php
static boolean loop_firstTime = true;
static int loopDelay = 5000;
static boolean debug_printIncoming;
static O externalSucker, externalPoster;

static TestRoom testRoom; // Set for testing

static class TestRoom {
  long roomID;
  new L<ChatLine> msgs;
  new L<S> presences;
  
  void post(S name, S text) {
    testPost(name, text, true);
  }
  
  void testPost(S name, S text, boolean isBot) {
    new ChatLine line;
    line.room = roomID;
    line.id = l(msgs)+1;
    line.who = name;
    line.text = text;
    line.isBot = isBot;
    msgs.add(line);
  }
}

static void testMode() {
  testMode(1);
}

static synchronized void testMode(long roomID) {
  testRoom = new TestRoom;
  testRoom.roomID = roomID;
}

static void enterRoom(long roomID) {
  if (testRoom != null) ret; // Do nothing on testing
  
  botRoom = roomID; // TODO: presence?
  lastSucked = 0;
  msgs = new L;
}

static void changeName(S name) {
  myBotName = unnull(name);
}

static S botifyName(S name) {
  name = unnull(name);
  if (!name.endsWith("bot"))
    name += " Bot";
  ret name;
}

static S getMyName() {
  S name = myBotName;
  if (empty(name))
    name = getProgramName();
  ret botifyName(name);
}

static synchronized void say(S text) {
  text = cleanLine(text);
  S name = getMyName();
  print(">> " + (testRoom != null ? "TEST" : "") + " " + roomNr() + " > " + name + " > " + text);
  if (testRoom != null)
    testRoom.post(name, text);
  else if (externalPoster != null)
    call(externalPoster, "say", name, text, mc());
  else
    sayInWebChatRoom(name, text, botRoom);
}

// should match server's line processing - so we can recognize
// our own lines
static S cleanLine(S line) {
  line = unnull(line);
  if (l(line) > maxLineLength) {
    print("Warning: Cutting line from " + l(line) + " to " + maxLineLength + " chars.");
    line = substring(line, 0, maxLineLength);
  }
  ret line.trim();
}

static void suckChat() {
  if (testRoom != null) {
    addMsgs(subList(testRoom.msgs, l(msgs)));
    ret;
  }
  
  ChatLine last = last(msgs);
  long lastID = last == null ? 0 : last.id;
  
  if (externalSucker != null) {
    addMsgs((L) quickImport(call(externalSucker, "getNewMessages", lastID)));
    ret;
  }
  
  if (now() < lastSucked + suckDelay) ret;
  try {
    L<ChatLine> newMsgs = suckWebChatRoom(getMyName(), botRoom, lastID, lastID == 0 ? historyGrab : 1000);
    addMsgs(newMsgs);
  } finally {
    lastSucked = now();
  }
}

static void addMsgs(L<ChatLine> l) {
  if (l == null) ret;
  if (debug_printIncoming)
    for (ChatLine line : l)
      print("INCOMING: " + line.who + " > " + line.text);
  for (ChatLine line : l) {
    hackfixUmlauts(line);
    msgs.add(line);
  }
}

// ISO to UTF-8 (lines coming from chat) - broken I think
static void hackfixUmlauts(ChatLine line) {
/*
  S s = line.text;
  new StringBuilder buf;
  for (int i = 0; i < l(s); i++) {
    int c = (int) s.charAt(i);
    if (c == 252) c = 195; // ü
    buf.append((char) c);
  }
  line.text = str(buf);
*/
}

static class MsgMarker {
  long room, idSeen;
  
  void advance(ChatLine line) {
    if (line == null) ret;
    idSeen = max(idSeen, line.id);
  }
  
  void setRoom(long roomID) {
    if (room != roomID) {
      room = roomID;
      idSeen = 0;
    }
  }
}

static L<ChatLine> msgsFrom(MsgMarker marker) {
  marker.setRoom(botRoom);
  ret msgsFrom(marker.idSeen);
}

static synchronized L<ChatLine> msgsFrom(long idSeen) {
  int i = l(msgs);
  while (i > 0 && msgs.get(i-1).id > idSeen)
    --i;
  L<ChatLine> l = subList(msgs, i);
  ret l;
}

static class WordDropper extends S2S {
  Set wordSet;
  
  *(S words) {
    wordSet = dropWords_preprocess(words);
  }
  
  S get(S s) {
    ret dropWords_impl(s, wordSet);
  }
}

static S getWordDropper_c1;
static S2S getWordDropper_c2;

static S2S getWordDropper(S wordsToDrop) {
  if (neq(getWordDropper_c1, wordsToDrop)) {
    getWordDropper_c1 = wordsToDrop;
    getWordDropper_c2 = new WordDropper(wordsToDrop);
  }
  ret getWordDropper_c2;
}

static new MsgMarker matchQuestion_seen;
static ChatLine matchQuestion_msg;

static boolean matchQuestion_dropping(S pat, S wordsToDrop) {
  ret matchQuestion(pat, getWordDropper(wordsToDrop));
}

static boolean matchQuestion(S pat) {
  ret matchQuestion(pat, null);
}

static boolean matchQuestion(S pat, S2S preprocessor) {
  suckChat();
  matchQuestion_msg = null;
  for (ChatLine line : msgsFrom(matchQuestion_seen)) {
    matchQuestion_seen.advance(line);
    S text = preprocess(line.text, preprocessor);
    if (debug_printIncoming)
      print("matchQuestion " + quote(text));
    if (match(pat, text, m)) {
      matchQuestion_msg = line;
      ret true;
    }
  }
  ret false;
}

static S whoAsks() {
  ret matchQuestion_msg.who;
}

static boolean haveAnswered(MsgMarker marker, S answer) {
  S myName = getMyName();
  for (ChatLine line : msgsFrom(marker))
    if (eq(line.who, myName) && eq(line.text, answer))
      ret true;
  ret false;
}

static void answerQuestion(S answer) {
  if (haveAnswered(matchQuestion_seen, answer))
    print("Have answered already :)");
  else
    say(answer);
}

static long roomNr() {
  ret botRoom;
}

static S roomNrString() {
  ret str(botRoom);
}

static boolean loop() {
  if (!licensed()) ret false;
  if (loop_firstTime)
    loop_firstTime = false;
  else if (testRoom != null)
    ret false;
  else
    sleep(loopDelay);
  ret true;
}

static synchronized void testPost(S name, S text, boolean isUser) {
  if (testRoom != null)
    testRoom.testPost(name, text, !isUser);
}

static void userPost(S text) {
  testPost("User", text, true);
}

// for test mode - get my responses
static synchronized L<S> getResponses() {
  new L<S> l;
  if (testRoom == null) ret l;
  S name = getMyName();
  for (ChatLine line : testRoom.msgs) {
    if (eq(line.who, name) && line.isBot)
      l.add(line.text);
  }
  ret l;
}

// string-to-string function
static abstract class S2S {
  abstract S get(S s);
}

static S preprocess(S text, S2S preprocessor) {
  pcall {
    if (preprocessor != null)
      text = preprocessor.get(text);
  }
  ret text;
}

static void printIncoming() {
  debug_printIncoming = true;
}

static synchronized L<S> getPresentNicks() {
  if (testRoom != null)
    ret cloneList(testRoom.presences);
    
  // TODO: cache this for a bit?
  ret getWebChatPresences(roomNr());
}

download  show line numbers  debug dex  old transpilations   

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

No comments. add comment

Snippet ID: #1002900
Snippet name: Web Chat API (include)
Eternal ID of this version: #1002900/1
Text MD5: 87ea57b865b1153f4656e245c7d75fee
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-04-05 23:32:20
Source code size: 6970 bytes / 303 lines
Pitched / IR pitched: No / No
Views / Downloads: 716 / 1549
Referenced in: #1002899 - Idiot Bot (Chat API Test)
#1002904 - Idiot Bot's Friend (answers his questions)
#1002907 - German Assistant
#1002919 - German Assistant 2 ("Kannst du mich sehen?")
#1002920 - Multi Web Chat Bot
#3000382 - Answer for ferdie (>> t = 1, f = 0)
#3000383 - Answer for funkoverflow (>> t=1, f=0 okay)