-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathserver.coffee
executable file
·138 lines (108 loc) · 3.93 KB
/
server.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
fs = require 'fs'
qs = require 'querystring'
url = require 'url'
http = require 'http'
request = require 'request'
program = require 'commander'
## Load config
try
global.config = JSON.parse fs.readFileSync './config.json', 'utf8'
catch e
global.config = {}
florinda = require './system'
brain = require './brains'
## Command-line options
program
.option('-n, --nochat', "Don't send messages")
.option('-s, --silent', "Don't send greeting on start")
.option('-v, --verbose', "Verbose mode, useful for debugging requests")
.option('-c, --cli', "Command-line mode")
.option('-u, --user [name]', 'Username for CLI/testing', 'John')
.parse process.argv
if program.cli
program.nochat = program.silent = true
## Make main objects global
# yeah, I could keep passing stuff around...
global.program = program
global.florinda = florinda
global.brain = brain
## Load commands
for file in fs.readdirSync './commands'
if /^[\w-_]+\.coffee$/.test file
try
require "./commands/#{file}"
console.log "loaded #{file}" if program.verbose
catch e
console.log "error loading #{file}"
## Create HTTP server
server = http.createServer (req, res) ->
pattern = ///
\[ # opening bracket
([^\]]+) # user name (anything NOT a closing bracket)
\] # closing bracket
\s # space
@florinda\,?\s? # partyhook pattern + optional space
(.+) # command given
///
params = url.parse(req.url, true).query
if req.method is 'GET'
if params?.reload == '1' and params.key == config.key
console.log "** RELOADING **"
res.end "** RELOADING **"
florinda.reload()
return
if params?.restart == '1' and params.key == config.key
console.log "** RESTARTING **"
res.end "** RESTARTING **"
florinda.restart()
return
command = params?.command
if command
user = 'john'
brain.receive user, command, (answer) ->
res.writeHead 200, { "Content-Type": 'text/plain' }
res.end answer
else
res.end 'no command'
else if req.method is 'POST'
body = ''
req.on 'data', (data) ->
body += data
req.on 'end', ->
# someone pushed to github, reload
try
payload = JSON.parse qs.parse(body).payload
catch e
payload = null
if payload and params?.reload == '1' and params.key == config.key
console.log "** RELOADING (push) **"
res.end "** RELOADING (push) **"
florinda.say "#{payload.commits[0]?.author.name} pushed to github, reloading...", ->
florinda.reload()
return
query = qs.parse(body)?.body
if query and matches = query.match(pattern)
[user, command] = matches.slice(1)
brain.receive user, command, florinda.say
return
res.end()
## Hello!
if not program.silent then florinda.say 'Hello!'
## Enter command-line mode
if program.cli
console.log "## Command-line mode:"
lastCommand = Date.now()
waitForInput = ->
program.prompt 'you: ', (command) ->
# ignore multiple calls (bug in commander?)
return if Date.now() - lastCommand < 1000
lastCommand = Date.now()
brain.receive program.user, command, (answer) ->
console.log answer
waitForInput()
waitForInput()
## Start HTTP server
else
PORT = config.port or 3333
server.listen PORT
console.log "server running on port #{PORT}"