msgs) {
ret map(msgs, func(Msg m) { litorderedmap(
time := m.time,
text := m.text,
ip := m.user.ipAddress,
cookie := m.user.cookie,
buttons := m.buttons,
auth := trueOrNull(m.auth),
botMark := trueOrNull(m.botMark),
nr := m.nr,
globalID := m.globalID
) });
}
svoid renderMessage(StringBuilder buf, S name, S time, S html, S id, S cookie, bool botMark, int nr, S parse, Bool goodParse) {
ByCookie bc = findConcept(ByCookie, +cookie);
S imgID = botMark ? #1008323 : #1008359;
if (nempty(cookie) && !botMark /*XXX*/ && bc != null) imgID = or(bc.avatarID, imgID);
S imgLink = snippetImgLink(imgID);
//if (nempty(id)) buf.append(hcomment("Msg ID: " + id));
if (nempty(parse))
parse = [[]] + parse + [[]];
buf.append([[
$NAME
$TIME
]].replace("$IMG", imgLink)
.replace("$NAME", name)
.replace("$TIME", time)
.replace("#ID#", id)
.replace("$STYLE", botMark
//? "style='text-align: right'"
//? "style='font-style: italic'"
? "style='font-family: Pacifico'"
: "")
.replace("", unnull(parse))
.replace("", html));
}
svoid appendButtons(StringBuilder buf, L buttons) {
S buttonsHtml = lines(map(buttons, func(S text) {
hsubmit(text, name := "btn")
}));
buf.append([[
]].replace("$BUTTONS", buttonsHtml);
}
svoid appendDate(StringBuilder buf, S date) {
buf.append([[
]].replace("DATE", date));
}
sS formatTime(long time) {
ret formatGMTWithOptionalDate_24(time);
}
sS formatMsgForLog(Msg m) {
ret htmlencode(m.nr + " " + formatDateAndTime(m.time)) + " - " + htmlencode(m.user.ipAddress + ": " + m.text);
}
static Conversation getConv(fS cookie) {
ret uniq_sync(Conversation, +cookie);
}
static L allMsgs() {
new L l;
for (Conversation c) {
for (L msgs : cloneList(c.oldDialogs)) addAll(l, msgs);
addAll(l, c.msgs);
}
ret l;
}
svoid processMsgCommands(Msg msg) {
new Matches m;
if (swic(msg.text, "avatar ", m)) {
S avatarID = fsI(trim($1));
BufferedImage img = loadImage2(avatarID);
if (img.getWidth() <= 400 && img.getHeight() <= 400)
cset(uniq(ByCookie, cookie := msg.user.cookie), +avatarID);
else fail("Avatar too big: " + avatarID);
}
}
svoid postMessage(Conversation conv, S message, bool botMark) {
message = shorten(message, messageLimit, " [...]");
S ip = clientIP();
print("Have message from " + ip + " at " + gmtWithSeconds() + " in thread " + currentThread() + ": " + quote(shorten(message, 80)));
if (startsWith(ip, "66.249.65."))
if (matchOneOf(message, "web * is invalid", "web * is correct"))
ret;
// anti hammer mechanism
S key = ip + " " + botMark;
if (eq(lastPosted.get(key), message)) {
print("Skipping same.");
ret;
}
lastPosted.put(key, message);
if (postingDisabled) ret;
if (superSimpleSpamTester(message)) {
print(logStructureWithDate("spam.log", "Ignoring spam message: " + quote(message)));
ret;
}
// ADD NOT SPAM MESSAGE
Msg msg = new Msg(clientIP(), cookieConcept(), message);
msg.botMark = botMark;
msg.auth = webAuthed();
//msg.nr = toInt(getOpt(last(conv.msgs), 'nr))+1;
if (conv.counter == 0) cset(conv, counter := conv.allCount());
cset(conv, counter := conv.counter+1);
msg.nr = conv.counter;
pcall {
msg.parse = ai_renderTriple(ai_tripelize(msg.text));
}
conv.add(msg);
print("Have " + l(conv.msgs) + " msgs in conversation " + conv.cookie + " after add");
}
svoid parseAll {
for (Msg m : allMsgs()) try {
m.parse = ai_renderTriple(ai_tripelize(m.text));
} catch print e {
m.parse = null;
}
change();
}