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)

1  
static S myBotName;
2  
static long botRoom = 1;
3  
static new Matches m; // for matching lines
4  
static int historyGrab = 10; // read last 10 lines from history
5  
static new L<ChatLine> msgs;
6  
static long lastSucked; // timestamp
7  
static long suckDelay = 2000; // suck every X ms
8  
static int maxLineLength = 1024; // should match groupchat.json.botsay.php
9  
static boolean loop_firstTime = true;
10  
static int loopDelay = 5000;
11  
static boolean debug_printIncoming;
12  
static O externalSucker, externalPoster;
13  
14  
static TestRoom testRoom; // Set for testing
15  
16  
static class TestRoom {
17  
  long roomID;
18  
  new L<ChatLine> msgs;
19  
  new L<S> presences;
20  
  
21  
  void post(S name, S text) {
22  
    testPost(name, text, true);
23  
  }
24  
  
25  
  void testPost(S name, S text, boolean isBot) {
26  
    new ChatLine line;
27  
    line.room = roomID;
28  
    line.id = l(msgs)+1;
29  
    line.who = name;
30  
    line.text = text;
31  
    line.isBot = isBot;
32  
    msgs.add(line);
33  
  }
34  
}
35  
36  
static void testMode() {
37  
  testMode(1);
38  
}
39  
40  
static synchronized void testMode(long roomID) {
41  
  testRoom = new TestRoom;
42  
  testRoom.roomID = roomID;
43  
}
44  
45  
static void enterRoom(long roomID) {
46  
  if (testRoom != null) ret; // Do nothing on testing
47  
  
48  
  botRoom = roomID; // TODO: presence?
49  
  lastSucked = 0;
50  
  msgs = new L;
51  
}
52  
53  
static void changeName(S name) {
54  
  myBotName = unnull(name);
55  
}
56  
57  
static S botifyName(S name) {
58  
  name = unnull(name);
59  
  if (!name.endsWith("bot"))
60  
    name += " Bot";
61  
  ret name;
62  
}
63  
64  
static S getMyName() {
65  
  S name = myBotName;
66  
  if (empty(name))
67  
    name = getProgramName();
68  
  ret botifyName(name);
69  
}
70  
71  
static synchronized void say(S text) {
72  
  text = cleanLine(text);
73  
  S name = getMyName();
74  
  print(">> " + (testRoom != null ? "TEST" : "") + " " + roomNr() + " > " + name + " > " + text);
75  
  if (testRoom != null)
76  
    testRoom.post(name, text);
77  
  else if (externalPoster != null)
78  
    call(externalPoster, "say", name, text, mc());
79  
  else
80  
    sayInWebChatRoom(name, text, botRoom);
81  
}
82  
83  
// should match server's line processing - so we can recognize
84  
// our own lines
85  
static S cleanLine(S line) {
86  
  line = unnull(line);
87  
  if (l(line) > maxLineLength) {
88  
    print("Warning: Cutting line from " + l(line) + " to " + maxLineLength + " chars.");
89  
    line = substring(line, 0, maxLineLength);
90  
  }
91  
  ret line.trim();
92  
}
93  
94  
static void suckChat() {
95  
  if (testRoom != null) {
96  
    addMsgs(subList(testRoom.msgs, l(msgs)));
97  
    ret;
98  
  }
99  
  
100  
  ChatLine last = last(msgs);
101  
  long lastID = last == null ? 0 : last.id;
102  
  
103  
  if (externalSucker != null) {
104  
    addMsgs((L) quickImport(call(externalSucker, "getNewMessages", lastID)));
105  
    ret;
106  
  }
107  
  
108  
  if (now() < lastSucked + suckDelay) ret;
109  
  try {
110  
    L<ChatLine> newMsgs = suckWebChatRoom(getMyName(), botRoom, lastID, lastID == 0 ? historyGrab : 1000);
111  
    addMsgs(newMsgs);
112  
  } finally {
113  
    lastSucked = now();
114  
  }
115  
}
116  
117  
static void addMsgs(L<ChatLine> l) {
118  
  if (l == null) ret;
119  
  if (debug_printIncoming)
120  
    for (ChatLine line : l)
121  
      print("INCOMING: " + line.who + " > " + line.text);
122  
  for (ChatLine line : l) {
123  
    hackfixUmlauts(line);
124  
    msgs.add(line);
125  
  }
126  
}
127  
128  
// ISO to UTF-8 (lines coming from chat) - broken I think
129  
static void hackfixUmlauts(ChatLine line) {
130  
/*
131  
  S s = line.text;
132  
  new StringBuilder buf;
133  
  for (int i = 0; i < l(s); i++) {
134  
    int c = (int) s.charAt(i);
135  
    if (c == 252) c = 195; // ü
136  
    buf.append((char) c);
137  
  }
138  
  line.text = str(buf);
139  
*/
140  
}
141  
142  
static class MsgMarker {
143  
  long room, idSeen;
144  
  
145  
  void advance(ChatLine line) {
146  
    if (line == null) ret;
147  
    idSeen = max(idSeen, line.id);
148  
  }
149  
  
150  
  void setRoom(long roomID) {
151  
    if (room != roomID) {
152  
      room = roomID;
153  
      idSeen = 0;
154  
    }
155  
  }
156  
}
157  
158  
static L<ChatLine> msgsFrom(MsgMarker marker) {
159  
  marker.setRoom(botRoom);
160  
  ret msgsFrom(marker.idSeen);
161  
}
162  
163  
static synchronized L<ChatLine> msgsFrom(long idSeen) {
164  
  int i = l(msgs);
165  
  while (i > 0 && msgs.get(i-1).id > idSeen)
166  
    --i;
167  
  L<ChatLine> l = subList(msgs, i);
168  
  ret l;
169  
}
170  
171  
static class WordDropper extends S2S {
172  
  Set wordSet;
173  
  
174  
  *(S words) {
175  
    wordSet = dropWords_preprocess(words);
176  
  }
177  
  
178  
  S get(S s) {
179  
    ret dropWords_impl(s, wordSet);
180  
  }
181  
}
182  
183  
static S getWordDropper_c1;
184  
static S2S getWordDropper_c2;
185  
186  
static S2S getWordDropper(S wordsToDrop) {
187  
  if (neq(getWordDropper_c1, wordsToDrop)) {
188  
    getWordDropper_c1 = wordsToDrop;
189  
    getWordDropper_c2 = new WordDropper(wordsToDrop);
190  
  }
191  
  ret getWordDropper_c2;
192  
}
193  
194  
static new MsgMarker matchQuestion_seen;
195  
static ChatLine matchQuestion_msg;
196  
197  
static boolean matchQuestion_dropping(S pat, S wordsToDrop) {
198  
  ret matchQuestion(pat, getWordDropper(wordsToDrop));
199  
}
200  
201  
static boolean matchQuestion(S pat) {
202  
  ret matchQuestion(pat, null);
203  
}
204  
205  
static boolean matchQuestion(S pat, S2S preprocessor) {
206  
  suckChat();
207  
  matchQuestion_msg = null;
208  
  for (ChatLine line : msgsFrom(matchQuestion_seen)) {
209  
    matchQuestion_seen.advance(line);
210  
    S text = preprocess(line.text, preprocessor);
211  
    if (debug_printIncoming)
212  
      print("matchQuestion " + quote(text));
213  
    if (match(pat, text, m)) {
214  
      matchQuestion_msg = line;
215  
      ret true;
216  
    }
217  
  }
218  
  ret false;
219  
}
220  
221  
static S whoAsks() {
222  
  ret matchQuestion_msg.who;
223  
}
224  
225  
static boolean haveAnswered(MsgMarker marker, S answer) {
226  
  S myName = getMyName();
227  
  for (ChatLine line : msgsFrom(marker))
228  
    if (eq(line.who, myName) && eq(line.text, answer))
229  
      ret true;
230  
  ret false;
231  
}
232  
233  
static void answerQuestion(S answer) {
234  
  if (haveAnswered(matchQuestion_seen, answer))
235  
    print("Have answered already :)");
236  
  else
237  
    say(answer);
238  
}
239  
240  
static long roomNr() {
241  
  ret botRoom;
242  
}
243  
244  
static S roomNrString() {
245  
  ret str(botRoom);
246  
}
247  
248  
static boolean loop() {
249  
  if (!licensed()) ret false;
250  
  if (loop_firstTime)
251  
    loop_firstTime = false;
252  
  else if (testRoom != null)
253  
    ret false;
254  
  else
255  
    sleep(loopDelay);
256  
  ret true;
257  
}
258  
259  
static synchronized void testPost(S name, S text, boolean isUser) {
260  
  if (testRoom != null)
261  
    testRoom.testPost(name, text, !isUser);
262  
}
263  
264  
static void userPost(S text) {
265  
  testPost("User", text, true);
266  
}
267  
268  
// for test mode - get my responses
269  
static synchronized L<S> getResponses() {
270  
  new L<S> l;
271  
  if (testRoom == null) ret l;
272  
  S name = getMyName();
273  
  for (ChatLine line : testRoom.msgs) {
274  
    if (eq(line.who, name) && line.isBot)
275  
      l.add(line.text);
276  
  }
277  
  ret l;
278  
}
279  
280  
// string-to-string function
281  
static abstract class S2S {
282  
  abstract S get(S s);
283  
}
284  
285  
static S preprocess(S text, S2S preprocessor) {
286  
  pcall {
287  
    if (preprocessor != null)
288  
      text = preprocessor.get(text);
289  
  }
290  
  ret text;
291  
}
292  
293  
static void printIncoming() {
294  
  debug_printIncoming = true;
295  
}
296  
297  
static synchronized L<S> getPresentNicks() {
298  
  if (testRoom != null)
299  
    ret cloneList(testRoom.presences);
300  
    
301  
  // TODO: cache this for a bit?
302  
  ret getWebChatPresences(roomNr());
303  
}

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: 715 / 1549
Referenced in: [show references]