Software /
code /
prosody-modules
Comparison
mod_vjud/mod_vjud.lua @ 753:9d5731af2c27
Merge with Oliver Gerlich
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Fri, 27 Jul 2012 14:29:59 +0100 |
parent | 742:da8f561d79b4 |
child | 787:cec49ee88c23 |
comparison
equal
deleted
inserted
replaced
752:9bbd99f2057a | 753:9d5731af2c27 |
---|---|
1 local dm_load = require "util.datamanager".load; | |
2 local dm_store = require "util.datamanager".store; | |
3 | |
4 local usermanager = require "core.usermanager"; | |
5 local dataforms_new = require "util.dataforms".new; | |
6 local jid_split = require "util.jid".prepped_split; | |
7 local vcard = module:require "vcard"; | |
8 local rawget, rawset = rawget, rawset; | |
9 | |
10 local st = require "util.stanza"; | |
11 local template = require "util.template"; | |
12 | |
13 local get_reply = template[[ | |
14 <query xmlns="jabber:iq:search"> | |
15 <instructions>Fill in one or more fields to search for any matching Jabber users.</instructions> | |
16 <first/> | |
17 <last/> | |
18 <nick/> | |
19 <email/> | |
20 </query> | |
21 ]].apply({}); | |
22 local item_template = template[[ | |
23 <item xmlns="jabber:iq:search" jid="{jid}"> | |
24 <first>{first}</first> | |
25 <last>{last}</last> | |
26 <nick>{nick}</nick> | |
27 <email>{email}</email> | |
28 </item> | |
29 ]]; | |
30 | |
31 module:add_feature("jabber:iq:search"); | |
32 | |
33 local opted_in; | |
34 function module.load() | |
35 opted_in = dm_load(nil, module.host, "user_index") or {}; | |
36 end | |
37 function module.unload() | |
38 dm_store(nil, module.host, "user_index", opted_in); | |
39 end | |
40 | |
41 local opt_in_layout = dataforms_new{ | |
42 title = "Search settings"; | |
43 instructions = "Do you want to appear in search results?"; | |
44 { | |
45 name = "searchable", | |
46 label = "Appear in search results?", | |
47 type = "boolean", | |
48 }, | |
49 }; | |
50 local vCard_mt = { | |
51 __index = function(t, k) | |
52 if type(k) ~= "string" then return nil end | |
53 for i=1,#t do | |
54 local t_i = rawget(t, i); | |
55 if t_i and t_i.name == k then | |
56 rawset(t, k, t_i); | |
57 return t_i; | |
58 end | |
59 end | |
60 end | |
61 }; | |
62 | |
63 local function get_user_vcard(user) | |
64 local vCard = dm_load(user, module.host, "vcard"); | |
65 if vCard then | |
66 vCard = st.deserialize(vCard); | |
67 vCard = vcard.from_xep54(vCard); | |
68 return setmetatable(vCard, vCard_mt); | |
69 end | |
70 end | |
71 | |
72 local at_host = "@"..module.host; | |
73 | |
74 module:hook("iq/host/jabber:iq:search:query", function(event) | |
75 local origin, stanza = event.origin, event.stanza; | |
76 | |
77 if stanza.attr.type == "get" then | |
78 origin.send(st.reply(stanza):add_child(get_reply)); | |
79 else -- type == "set" | |
80 local query = stanza.tags[1]; | |
81 local first, last, nick, email = | |
82 (query:get_child_text"first" or false), | |
83 (query:get_child_text"last" or false), | |
84 (query:get_child_text"nick" or false), | |
85 (query:get_child_text"email" or false); | |
86 | |
87 if not ( first or last or nick or email ) then | |
88 origin.send(st.error_reply(stanza, "modify", "not-acceptable", "All fields were empty")); | |
89 return true; | |
90 end | |
91 | |
92 local reply = st.reply(stanza):query("jabber:iq:search"); | |
93 | |
94 local username, hostname = jid_split(email); | |
95 if hostname == module.host and username and usermanager.user_exists(username, hostname) then | |
96 local vCard = get_user_vcard(username); | |
97 if vCard then | |
98 reply:add_child(item_template.apply{ | |
99 jid = username..at_host; | |
100 first = vCard.N and vCard.N[2] or nil; | |
101 last = vCard.N and vCard.N[1] or nil; | |
102 nick = vCard.NICKNAME and vCard.NICKNAME[1] or username; | |
103 email = vCard.EMAIL and vCard.EMAIL[1] or nil; | |
104 }); | |
105 end | |
106 else | |
107 for username in pairs(opted_in) do | |
108 local vCard = get_user_vcard(username); | |
109 if vCard and ( | |
110 (vCard.N and vCard.N[2] == first) or | |
111 (vCard.N and vCard.N[1] == last) or | |
112 (vCard.NICKNAME and vCard.NICKNAME[1] == nick) or | |
113 (vCard.EMAIL and vCard.EMAIL[1] == email)) then | |
114 reply:add_child(item_template.apply{ | |
115 jid = username..at_host; | |
116 first = vCard.N and vCard.N[2] or nil; | |
117 last = vCard.N and vCard.N[1] or nil; | |
118 nick = vCard.NICKNAME and vCard.NICKNAME[1] or username; | |
119 email = vCard.EMAIL and vCard.EMAIL[1] or nil; | |
120 }); | |
121 end | |
122 end | |
123 end | |
124 origin.send(reply); | |
125 end | |
126 return true; | |
127 end); | |
128 | |
129 local function opt_in_handler(self, data, state) | |
130 local username, hostname = jid_split(data.from); | |
131 if state then -- the second return value | |
132 if data.action == "cancel" then | |
133 return { status = "canceled" }; | |
134 end | |
135 | |
136 if not username or not hostname or hostname ~= module.host then | |
137 return { status = "error", error = { type = "cancel", | |
138 condition = "forbidden", message = "Invalid user or hostname." } }; | |
139 end | |
140 | |
141 local fields = opt_in_layout:data(data.form); | |
142 opted_in[username] = fields.searchable or nil | |
143 | |
144 return { status = "completed" } | |
145 else -- No state, send the form. | |
146 return { status = "executing", actions = { "complete" }, | |
147 form = { layout = opt_in_layout, data = { searchable = opted_in[username] } } }, true; | |
148 end | |
149 end | |
150 | |
151 local adhoc_new = module:require "adhoc".new; | |
152 local adhoc_vjudsetup = adhoc_new("Search settings", "vjudsetup", opt_in_handler);--, "self");-- and nil); | |
153 module:depends"adhoc"; | |
154 module:provides("adhoc", adhoc_vjudsetup); | |
155 |