Merge from waqas
[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 = handlers[to]; -- get the handler\r
61                 if not handler then -- if not found then use default handler\r
62                         if to_node then\r
63                                 handler = handlers["*defaultnode"];\r
64                         else\r
65                                 handler = handlers["*defaulthost"];\r
66                         end\r
67                 end\r
68                 local found; -- to keep track of any handlers found\r
69                 if handler then\r
70                         for _, h in ipairs(handler) do\r
71                                 if h(reply, to, from, node) then found = true; end\r
72                         end\r
73                 end\r
74                 if to_node then -- handlers which get called always\r
75                         handler = handlers["*node"];\r
76                 else\r
77                         handler = handlers["*host"];\r
78                 end\r
79                 if handler then -- call always called handler\r
80                         for _, h in ipairs(handler) do\r
81                                 if h(reply, to, from, node) then found = true; end\r
82                         end\r
83                 end\r
84                 if found then return reply; end -- return the reply if there was one\r
85                 return st.error_reply(stanza, "cancel", "service-unavailable");\r
86         end\r
87 end\r
88 \r
89 function new()\r
90         return {\r
91                 item_handlers = {};\r
92                 info_handlers = {};\r
93                 addDiscoItemsHandler = addDiscoItemsHandler;\r
94                 addDiscoInfoHandler = addDiscoInfoHandler;\r
95                 handle = handle;\r
96         };\r
97 end\r
98 \r
99 return _M;\r