-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.moon
95 lines (80 loc) · 2.61 KB
/
main.moon
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
#!/usr/bin/env moon
--- Create and manage IRC bots.
-- @script main.moon
-- @author Ryan "ChickenNuggers" <[email protected]>
Logger = require 'logger' -- vim:set noet sts=0 sw=3 ts=3:
cqueues = require 'cqueues'
lfs = require 'lfs'
moonscript = require "moonscript"
import IRCClient from require 'lib.irc'
wd = lfs.currentdir()
Logger.set_debug true if os.getenv 'DEBUG'
pcall -> -- use StackTracePlus if available; it's much better than builtin
debug.traceback = require("StackTracePlus").stacktrace
load_modules = (folder)->
for file in lfs.dir folder
if file\match "%.moon$"
path = "#{folder}/#{file}"
IRCClient\with_context path, assert moonscript.loadfile path
load_modules_in_plugin_folders = ->
for module_folder in *{'handlers', 'plugins', 'modules', 'commands'}
full_path = wd .. '/' .. module_folder
load_modules full_path if lfs.attributes(full_path, 'mode') == 'directory'
load_modules_in_plugin_folders!
bots = {}
conf_home = os.getenv('XDG_CONFIG_HOME') or os.getenv('HOME') .. '/.config'
for file in lfs.dir "#{conf_home}/moonmoon"
if file\match "%.lua$"
local data
env =
bot: (name)->
return (file_data)->
file_data.name = name
file_data.file = file
data = file_data
async: (fn)->
return (...)->
args = {...}
require("queue")\wrap -> fn table.unpack args
setmetatable(env, __index: _ENV)
fn = assert loadfile("#{conf_home}/moonmoon/#{file}", nil, env)
fn!
unless data and data.server
print "Missing `server` field: [#{file}]"
continue
if os.getenv 'DEBUG'
for key, value in pairs data
if type(value) == "string" then
print ("%q: %q")\format key, value
else
print ("%q: %s")\format key, value
bot = IRCClient data.server, data.port, data
bot\with_context "config", ->
if bot.config.custom_commands
for command, handler in pairs bot.config.custom_commands
bot\add_command command, handler
table.insert(bots, bot)
queue = cqueues.new!
package.loaded["queue"] = queue -- for use in modules
for bot in *bots
queue\wrap ->
while true
local success
for i=1, 3 do -- three tries
ok, err = pcall bot.connect, bot
success = ok
if not ok
Logger.print Logger.level.error .. '*** Unable to connect: ' .. bot.config.server
Logger.debug Logger.level.error .. '*** ' .. err
else
break
if not success
Logger.print Logger.level.fatal .. '*** Not connecting anymore for: ' .. bot.config.file
return
ok, err = pcall -> bot\loop!
if not ok then
Logger.print Logger.level.error .. err
while not queue\empty!
ok, err = queue\step!
if not ok
Logger.debug "#{Logger.level.error} *** #{err}"