-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.coffee
87 lines (76 loc) · 2.39 KB
/
app.coffee
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
Twitter = require("twitter")
CoffeeScript = require("coffee-script")
request = require("request")
Sandbox = require("./sandbox")
BOT_ID = "coffee_repl"
reg = new RegExp("@#{BOT_ID}\\s+([\\s\\S]+)")
twit = new Twitter(require("./#{BOT_ID}_key"))
sandbox = new Sandbox (result)=> @tweet(result)
main = ->
tweet("restarted. "+Date())
setInterval((->
if (new Date()).getMinutes() is 0
tweet("periodical report. "+Date())
), 60*1000)
twit.stream "user", (stream)->
stream.on "data", ({id_str, user, text})->
if text? and screen_name isnt BOT_ID and reg.test(text)
screen_name = user.screen_name
logging("onTweet", [id_str, screen_name, text])
compile unescapeCharRef(reg.exec(text)[1]), ({data, error})->
if error?
then tweet("@#{screen_name} #{data}", {"in_reply_to_status_id": id_str})
else
logging("JavaScript", [data])
sandbox.eval data, (result)->
tweet("@#{screen_name} #{result}", {"in_reply_to_status_id": id_str})
logging = (id, ary=[])->
console.log "######## #{id} ########"
console.log "## #{Date()}"
ary.forEach (v)->
console.log "## #{v}"
tweet = (str, opt={}, i=0)->
_str = cutStr(140, str)
logging("sendTweet", [str])
twit.updateStatus _str, opt, (data)->
if !data.statusCode?
then logging("succeeded")
else
logging("failed", [data])
delay = Math.pow(i, 2)*600
logging("retrying", [delay])
setTimeout((=> tweet("."+_str, opt, i+1)), delay)
undefined
cutStr = (n, str)->
if str.length <= n
then str
else str.substr(0, n-3) + "..."
cs2js = (csCode)->
CoffeeScript.compile(csCode.split("\n").join("\n "), {bare:true})
unescapeCharRef = (str)->
[
[""", '"']
["&", "&"]
["'", "'"]
["<", "<"]
[">", ">"]
].reduce(((_str, [before, after])=>
_str.split(before).join(after)
), str)
compile = (code, next)->
if url = (/^\.import\s+([\S]+)/.exec(code) or ["", false])[1]
logging("wget", [url])
request url, (error, response, body)->
if !error && response.statusCode is 200
then next({data: body})
else next({error: true, data: error})
else
csCode = "\n"+code+"\n"
logging("CoffeeScript", [csCode])
try
data = cs2js(csCode)
setImmediate -> next({data: data})
catch err
setImmediate -> next({error: true, data: ""+err})
undefined
main()