Change modules to use the new add_feature module API method.
[prosody.git] / util / discohelper.lua
1 -- Prosody IM v0.1
2 -- Copyright (C) 2008 Matthew Wild
3 -- Copyright (C) 2008 Waqas Hussain
4 -- 
5 -- This program is free software; you can redistribute it and/or
6 -- modify it under the terms of the GNU General Public License
7 -- as published by the Free Software Foundation; either version 2
8 -- of the License, or (at your option) any later version.
9 -- 
10 -- This program is distributed in the hope that it will be useful,
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 -- GNU General Public License for more details.
14 -- 
15 -- You should have received a copy of the GNU General Public License
16 -- along with this program; if not, write to the Free Software
17 -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 --
19
20
21 \r
22 local t_insert = table.insert;\r
23 local jid_split = require "util.jid".split;\r
24 local ipairs = ipairs;\r
25 local st = require "util.stanza";\r
26 \r
27 module "discohelper";\r
28 \r
29 local function addDiscoItemsHandler(self, jid, func)\r
30         if self.item_handlers[jid] then\r
31                 t_insert(self.item_handlers[jid], func);\r
32         else\r
33                 self.item_handlers[jid] = {func};\r
34         end\r
35 end\r
36 \r
37 local function addDiscoInfoHandler(self, jid, func)\r
38         if self.info_handlers[jid] then\r
39                 t_insert(self.info_handlers[jid], func);\r
40         else\r
41                 self.info_handlers[jid] = {func};\r
42         end\r
43 end\r
44 \r
45 local function handle(self, stanza)\r
46         if stanza.name == "iq" and stanza.tags[1].name == "query" then\r
47                 local query = stanza.tags[1];\r
48                 local to = stanza.attr.to;\r
49                 local from = stanza.attr.from\r
50                 local node = query.attr.node or "";\r
51                 local to_node, to_host = jid_split(to);\r
52 \r
53                 local reply = st.reply(stanza):query(query.attr.xmlns);\r
54                 local handlers;\r
55                 if query.attr.xmlns == "http://jabber.org/protocol/disco#info" then -- select handler set\r
56                         handlers = self.info_handlers;\r
57                 elseif query.attr.xmlns == "http://jabber.org/protocol/disco#items" then\r
58                         handlers = self.item_handlers;\r
59                 end\r
60                 local handler;
61                 local found; -- to keep track of any handlers found
62                 if to_node then -- handlers which get called always\r
63                         handler = handlers["*node"];\r
64                 else\r
65                         handler = handlers["*host"];\r
66                 end\r
67                 if handler then -- call always called handler\r
68                         for _, h in ipairs(handler) do\r
69                                 if h(reply, to, from, node) then found = true; end\r
70                         end\r
71                 end\r
72                 handler = handlers[to]; -- get the handler
73                 if not handler then -- if not found then use default handler
74                         if to_node then
75                                 handler = handlers["*defaultnode"];
76                         else
77                                 handler = handlers["*defaulthost"];
78                         end
79                 end
80                 if handler then
81                         for _, h in ipairs(handler) do
82                                 if h(reply, to, from, node) then found = true; end
83                         end
84                 end
85                 if found then return reply; end -- return the reply if there was one\r
86                 return st.error_reply(stanza, "cancel", "service-unavailable");\r
87         end\r
88 end\r
89 \r
90 function new()\r
91         return {\r
92                 item_handlers = {};\r
93                 info_handlers = {};\r
94                 addDiscoItemsHandler = addDiscoItemsHandler;\r
95                 addDiscoInfoHandler = addDiscoInfoHandler;\r
96                 handle = handle;\r
97         };\r
98 end\r
99 \r
100 return _M;\r