summaryrefslogtreecommitdiff
path: root/main.lua
blob: 103a18c1218c0bc830a958207262bbed0441f83a (plain)
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
local cqueues = require'cqueues'
local signal = require'cqueues.signal'
local class = require'r.class'
local pprint = require'pprint'

local config = require'config'
local Thing = require'thing'
local Log = require 'log'
local Store = require 'store'

local pylon_classes = {
	irc = require'irc.pylon',
	xmpp = require'xmpp.pylon',
	discord = require'discord.pylon',
	nanochat = require'nanochat.pylon',
	quaddle = require'quaddle.pylon',
}

local Wilson = class()
function Wilson.make(cls, conf)
	local tlc = conf.top.level or {}
	local self = setmetatable({
		pylons={},
		busses={},
		cq = cqueues.new(),
		log = Log('(toplevel)',tlc.loglevel or 'info'),
		store = Store(),
	}, Wilson)
	for name, pylon_conf in pairs(conf.pylon) do
		pylon_conf.name = name
		local pylon_class = pylon_classes[pylon_conf.type]
		assert(pylon_class, "no such pylon type "..pylon_conf.type)
		self.pylons[name] = pylon_class:make(self, pylon_conf)
		self.log("constructed pylon",name,pylon_conf.type)
	end
	for name, bus_conf in pairs(conf.bus) do
		local bus = {}
		for _, item in ipairs(bus_conf) do
			local pylon_name, channel_id = item[1], item[2]
			local pylon = self.pylons[pylon_name]
			assert(pylon,"no such pylon named "..pylon_name)
			table.insert(bus, Thing(pylon, channel_id))
		end
		self.log("constructed bus  ",name,'with '..#bus_conf..' channels')
		self.busses[name] = bus
	end
	return self
end

function Wilson.add_channels_for(self, pylon)
	if not pylon.channels then return end
	for busname, bus in pairs(busses) do
		for _, channel in ipairs(bus) do
			if  channel.pylon == pylon
				and not pylon.channels[channel.id]
			then
				pylon:add_channel(channel)
end end end end

function Wilson._find_bus(self, channel)
	for name, bus in pairs(self.busses) do
		for _, q in ipairs(bus) do if q == channel then return bus end end
	end
	self.log:warn("unfound bus for",channel) end
function Wilson.deliver(self, message)
	local bus = self:_find_bus(assert(message.channel))
	if bus then
		self.store:store(message)
		for _, dest_channel in ipairs(bus) do
			if message.channel ~= dest_channel then
				self.log:debug(message.channel, "-->", dest_channel, message)
				dest_channel.pylon:post(dest_channel, message)
end end end end
function Wilson.run(self)
	for pylonname, pylon in pairs(self.pylons) do
		self.cq:wrap(pylon.run, pylon)
		self.log("now running pylon", pylonname)
	end
	self.cq:wrap(self.store.run, self.store)
	self.cq:wrap(self.hup, self)
	self.log:loop(self.cq)
end

function Wilson.hup(self)
	signal.block(signal.SIGHUP)
	local sl = signal.listen(signal.SIGHUP)
	while true do
		local s = sl:wait()
		self:reload_config()
	end
end

local config_file = assert(io.open("wilson.ini","r"))
local conf = config.parse(config_file)
config_file:close()
local wilson = Wilson:make(conf)
wilson:run()