Comparison

mod_vjud/mod_vjud.lua @ 715:b1268d3aa6ce

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