-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcore.clj
71 lines (59 loc) · 2.34 KB
/
core.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
(ns repl-bot.core
(:require [repl-bot.discord :as discord]
[environ.core :refer [env]]
[clojure.tools.nrepl :as repl]
[clojail.testers :refer [secure-tester-without-def blanket]]
[clojure.stacktrace :refer [root-cause]]
[clojail.core :refer [sandbox]])
(:gen-class)
(:import (java.io StringWriter)
(java.util.concurrent TimeoutException)))
(defn eval-form [form sbox]
(with-open [out (StringWriter.)]
(let [result (sbox form {#'*out* out})]
{:expr form
:result [out result]})))
(defonce session (atom {:sb nil}))
(defn eval-string [expr sbox]
(let [form (binding [*read-eval* false] (read-string expr))]
(eval-form form sbox)))
(def try-clojure-tester
(conj secure-tester-without-def (blanket "tryclojure" "noir")))
(defn make-sandbox []
(sandbox try-clojure-tester
:timeout 2000
:init '(do (require '[clojure.repl :refer [doc source]])
(future (Thread/sleep 600000)
(-> *ns* .getName remove-ns)))))
(defn find-sb [old]
(if-let [sb (get old "sb")]
old
(assoc old "sb" (make-sandbox))))
(defn eval-request [expr]
(try
(eval-string expr (get (swap! session find-sb) "sb"))
(catch TimeoutException _
{:error true :message "Execution Timed Out!"})
(catch Exception e
{:error true :message (str (root-cause e))})))
(defn log-event [type data]
(println "\nReceived: " type " -> " data))
(defn repl-command [type data]
(let [command (get data "content")
channel (get data "channel_id")
user (get-in data ["author" "username"])]
(when (and (= (some-> channel str Long/parseLong) 315213511120912386)
(not (re-find #"^\s*=>" command))
(not (re-find #"^\s*;" command))
(not (re-find #"^\s*\(comment" command))
(not (= user "repl-bot")))
(discord/answer data (some-> command eval-request :result last)))))
; channel-id 315213511120912386
(defn -main [& args]
(let [{:keys [token nrepl-host nrepl-port] :or {nrepl-host "localhost"
nrepl-port 9876}} env]
(discord/connect token
{
"MESSAGE_CREATE" [repl-command]
"ALL_OTHER" [log-event]}
true)))