Warning: session_start(): open(/var/lib/php/sessions/sess_ne94vs8u93eq3hf3j8pp6f9hkb, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
!7
set flag DynModule. // for transpilation
cmodule2 GazelleMultiBot > DynGazelleBot {
switchable int maxEvalResultLength = oneMegabyte_int();
switchable double evalTimeout = 60.0;
switchable long botProcessed; // timestamp of last post processed by bots
transient new L bots;
Map allPosts = syncTreeMap();
class Bot {
S name;
*() {}
*(S *name) {}
*(S *name, IVF1 *handlePost) {}
swappable void handlePost(GazellePost post) {}
GazelleBotCred cred() { ret GazelleBotCred(_user, _botToken, name); }
void postReply(GazellePost post, S text, S type) {
gazelle_createPost(cred(), text, type, refs := post.id);
}
}
start {
dm_useLocalMechListCopies();
grabLoop.handlePosts = posts -> {
dm_mediumRefreshTranspiler();
grabLoop.handlePosts_base(posts);
for (GazellePost post : posts)
setField(botProcessed := max(botProcessed, post.modified));
};
// legacy conversion to sort allPosts
setField_noCheck(allPosts := asSyncTreeMap(allPosts));
bots.add(new Bot("Math Bot", post -> {
if (post.creating) ret;
gazelle_mathBot1_handlePost_2(_user, _botToken, post);
}));
bots.add(new Bot("Code Safety Checker") {
void handlePost(GazellePost post) {
if (post.creating) ret;
if (eqic(post.type, "JavaX Code"))
gazelle_createPost(cred(), codeSafetyCheckResult(post.text), "Code Safety", refs := post.id);
}
});
bots.add(new Bot("Safe Code Runner") {
void handlePost(GazellePost post) {
if (post.creating) ret;
if (eqic(post.type, "JavaX Code")) {
S code = post.text;
if (isCodeSafe(code)) {
code = tok_addReturn(code);
// define implicit vars and functions
if (containsJavaToken(code, "post")) {
long ref = gazelle_firstPostRef(post.id);
if (ref != 0)
code = "S post = " + quote(gazelle_text(ref)) + ";\n" + code;
}
if (containsJavaToken(code, "post2")) {
long ref = gazelle_firstPostRef(gazelle_firstPostRef(post.id));
if (ref != 0)
code = "S post2 = " + quote(gazelle_text(ref)) + ";\n" + code;
}
if (containsJavaToken(code, "getAllPosts"))
code = [[
embedded Cl getAllPosts() {
ret (Cl) quickImport(dm_call(dm_current_generic(), "getAllPosts"));
}
]] + code;
printWithIndent("CODE> ", code);
S out = shorten(maxEvalResultLength, runCode(code));
gazelle_createPost(cred(), out, "Code Result", refs := post.id);
}
}
}
});
bots.add(new Bot("Run Code On All Posts") {
void handlePost(GazellePost post) {
if (post.creating) ret;
if (eqic(post.type, "Instruction") && match("Please run this code on all posts", post.text)) {
long ref = gazelle_firstPostRef(post.id);
if (ref == 0) ret;
S code = gazelle_text(ref);
if (!isCodeSafe(code)) ret;
S code2 = "ret func(S post) { " + code + " };";
O function = dm_javaEval(code2);
new LS lines;
S out = shorten(maxEvalResultLength, runCode(code));
for (GazellePost post2 : cloneValues(allPosts)) {
lines.add("Post " + post2.id + " (" + quote(shorten(20, post2.text)) + "): " + shorten(80, runFunc(() -> callF(function, post2.text))));
}
gazelle_createPost(cred(), lines(lines), "Code Result", refs := post.id);
}
}
});
bots.add(new Bot("Mark identifiers safe") {
void handlePost(GazellePost post) {
if (post.creating) ret;
if (/*eqic(post.type, "Instruction")
&&*/ post.creator.isMaster
&& match("Mark safe", post.text)) {
S text = getPost(first(post.postRefs)).text;
LS ids = tok_identifiersInOrder(regexpFirstGroupIC("Unknown identifiers: (.+)", text));
print("Marking safe: " + ids);
postReply(post, markSafe(ids), "Marked safe");
}
}
});
bots.add(new Bot("Post Deleter") {
void handlePost(GazellePost post) {
if (post.creating) ret;
if (eqic(post.type, "Instruction")
&& post.creator.isMaster
&& match("Delete mentioned posts", post.text)) {
long ref = gazelle_firstPostRef(post.id);
if (ref == 0) ret;
S text = gazelle_text(ref);
L postIDs = allToLong(regexpAllFirstGroups(gazelle_postMentionRegexp(), text));
print("Deleting posts: " + postIDs);
if (nempty(postIDs)) {
Map result = gazelle_deletePosts(cred(), postIDs);
postReply(post, str(result));
} else
postReply(post, "No mentioned posts found");
}
}
});
}
void handlePost(GazellePost post) {
allPosts.put(post.id, post);
change();
if (post.modified > botProcessed) {
print("modified: " + post.modified + "/" + botProcessed);
for (Bot bot : bots) pcall {
bot.handlePost(post);
}
}
}
// assumes code is safety-checked
S runCode(S code) {
ret runFunc(() -> str_shortenSynthetic(dm_javaEval(code)));
}
S runFunc(IF0 f) {
ret str_shortenSynthetic(evalWithTimeoutOrException(evalTimeout, func {
try {
ret str_shortenSynthetic(f!);
} catch e {
ret getStackTrace(e);
}
}));
}
L repliesTo(GazellePost post) {
ret filter(values(allPosts), p -> contains(p.postRefs, post.id));
}
L repliesWithTag(GazellePost post, S tag) {
Pair pair = pair(post.id, upper(tag));
ret filter(repliesTo(post), p -> contains(mapPairsB toUpper(p.taggedRefs()), pair);
}
GazellePost getPost(long id) {
ret allPosts.get(id);
}
Cl getAllPosts() {
ret values(allPosts);
}
CodeSafetyChecker codeSafetyChecker() {
new CodeSafetyChecker checker;
checker.init();
checker.markSafe("getAllPosts");
ret checker;
}
S codeSafetyCheckResult(S code) {
CodeSafetyChecker checker = codeSafetyChecker();
checker.checkCode(code);
ret checker.verbalCheckResult();
}
bool isCodeSafe(S code) {
CodeSafetyChecker checker = codeSafetyChecker();
checker.checkCode(code);
ret checker.isSafe();
}
}