comparison mod_archive/mod_archive.lua @ 165:fd8d76daad97

mod_archive: preference handling is done.
author shinysky<shinysky1986(AT)gmail.com>
date Sun, 06 Jun 2010 00:04:04 +0800
parents 9a37898f4f7c
children ac826882a8cf
comparison
equal deleted inserted replaced
164:0b238b2b0801 165:fd8d76daad97
4 -- This project is MIT/X11 licensed. Please see the 4 -- This project is MIT/X11 licensed. Please see the
5 -- COPYING file in the source package for more information. 5 -- COPYING file in the source package for more information.
6 -- 6 --
7 7
8 local st = require "util.stanza"; 8 local st = require "util.stanza";
9 local dm = require "util.datamanager" 9 local dm = require "util.datamanager";
10
11 local PREFS_DIR = "archive_prefs";
12 local ARCHIVE_DIR = "archive";
10 13
11 module:add_feature("urn:xmpp:archive"); 14 module:add_feature("urn:xmpp:archive");
12 module:add_feature("urn:xmpp:archive:auto"); 15 module:add_feature("urn:xmpp:archive:auto");
13 module:add_feature("urn:xmpp:archive:manage"); 16 module:add_feature("urn:xmpp:archive:manage");
14 module:add_feature("urn:xmpp:archive:manual"); 17 module:add_feature("urn:xmpp:archive:manual");
15 module:add_feature("urn:xmpp:archive:pref"); 18 module:add_feature("urn:xmpp:archive:pref");
16 19
20 ------------------------------------------------------------
21 -- Utils
22 ------------------------------------------------------------
23 local function load_prefs(node, host, dir)
24 return st.deserialize(dm.load(node, host, dir or PREFS_DIR));
25 end
26
27 local function store_prefs(data, node, host, dir)
28 dm.store(node, host, dir or PREFS_DIR, st.preserialize(data));
29 end
30
31 ------------------------------------------------------------
32 -- Preferences
33 ------------------------------------------------------------
17 local function preferences_handler(event) 34 local function preferences_handler(event)
18 local origin, stanza = event.origin, event.stanza; 35 local origin, stanza = event.origin, event.stanza;
19 module:log("debug", "-- Enter preferences_handler()"); 36 module:log("debug", "-- Enter preferences_handler()");
20 module:log("debug", "-- pref:\n%s", tostring(stanza)); 37 module:log("debug", "-- pref:\n%s", tostring(stanza));
21 if stanza.attr.type == "get" then 38 if stanza.attr.type == "get" then
22 -- dm.store(origin.username, origin.host, "archive_prefs", st.preserialize(reply.tags[1])); 39 local data = load_prefs(origin.username, origin.host);
23 local data = st.deserialize(dm.load(origin.username, origin.host, "archive_prefs"));
24 if data then 40 if data then
25 origin.send(st.reply(stanza):add_child(data)); 41 origin.send(st.reply(stanza):add_child(data));
26 else 42 else
27 local reply = st.reply(stanza):tag('pref', {xmlns='urn:xmpp:archive'}); 43 local reply = st.reply(stanza):tag('pref', {xmlns='urn:xmpp:archive'});
28 reply:tag('default', {otr='concede', save='false', unset='true'}):up(); 44 reply:tag('default', {otr='concede', save='false', unset='true'}):up();
29 reply:tag('method', {type='auto', use='concede'}):up(); 45 reply:tag('method', {type='auto', use='concede'}):up();
30 reply:tag('method', {type='local', use='concede'}):up(); 46 reply:tag('method', {type='local', use='concede'}):up();
31 reply:tag('method', {type='manual', use='concede'}):up(); 47 reply:tag('method', {type='manual', use='concede'}):up();
32 reply:tag('auto', {save='false'}):up(); 48 reply:tag('auto', {save='false'}):up();
33 origin.send(reply); 49 origin.send(reply);
34 -- origin.send(st.reply(stanza)); 50 end
35 end
36 return true;
37 elseif stanza.attr.type == "set" then 51 elseif stanza.attr.type == "set" then
38 return false; 52 local node, host = origin.username, origin.host;
39 end 53 local data = load_prefs(node, host);
54 if not data then
55 data = st.stanza('pref', {xmlns='urn:xmpp:archive'});
56 data:tag('default', {otr='concede', save='false'}):up();
57 data:tag('method', {type='auto', use='concede'}):up();
58 data:tag('method', {type='local', use='concede'}):up();
59 data:tag('method', {type='manual', use='concede'}):up();
60 data:tag('auto', {save='false'}):up();
61 end
62 local elem = stanza.tags[1].tags[1]; -- iq:pref:xxx
63 if not elem then return false end
64 -- "default" | "item" | "session" | "method"
65 -- FIXME there may be many item/session/method sections!!
66 elem.attr["xmlns"] = nil; -- TODO why there is an extra xmlns attr?
67 if elem.name == "default" then
68 local setting = data:child_with_name(elem.name)
69 for k, v in pairs(elem.attr) do
70 setting.attr[k] = v;
71 end
72 -- setting.attr["unset"] = nil
73 elseif elem.name == "item" then
74 local found = false;
75 for child in data:children() do
76 -- TODO bare JID or full JID?
77 if child.name == elem.name and child.attr["jid"] == elem.attr["jid"] then
78 for k, v in pairs(elem.attr) do
79 child.attr[k] = v;
80 end
81 found = true;
82 break;
83 end
84 end
85 if not found then
86 data:tag(elem.name, elem.attr):up();
87 end
88 elseif elem.name == "session" then
89 local found = false;
90 for child in data:children() do
91 if child.name == elem.name and child.attr["thread"] == elem.attr["thread"] then
92 for k, v in pairs(elem.attr) do
93 child.attr[k] = v;
94 end
95 found = true;
96 break;
97 end
98 end
99 if not found then
100 data:tag(elem.name, elem.attr):up();
101 end
102 elseif elem.name == "method" then
103 local newpref = stanza.tags[1]; -- iq:pref
104 for _, e in ipairs(newpref.tags) do
105 -- if e.name ~= "method" then continue end
106 local found = false;
107 for child in data:children() do
108 if child.name == "method" and child.attr["type"] == e.attr["type"] then
109 child.attr["use"] = e.attr["use"];
110 found = true;
111 break;
112 end
113 end
114 if not found then
115 data:tag(e.name, e.attr):up();
116 end
117 end
118 end
119 store_prefs(data, node, host);
120 origin.send(st.reply(stanza));
121 local user = bare_sessions[node.."@"..host];
122 local push = st.iq({type="set"});
123 push = push:tag('pref', {xmlns='urn:xmpp:archive'});
124 if elem.name == "method" then
125 for child in data:children() do
126 if child.name == "method" then
127 push:add_child(child);
128 end
129 end
130 else
131 push:add_child(elem);
132 end
133 push = push:up();
134 for _, res in pairs(user and user.sessions or NULL) do -- broadcast to all resources
135 if res.presence then -- to resource
136 push.attr.to = res.full_jid; -- TODO how to gen the message that new modes're set?
137 res.send(push);
138 end
139 end
140 end
141 return true;
142 end
143
144 local function itemremove_handler(event)
145 local origin, stanza = event.origin, event.stanza;
146 if stanza.attr.type ~= "set" then
147 return false;
148 end
149 local elem = stanza.tags[1].tags[1];
150 if not elem or elem.name ~= "item" then
151 return false;
152 end
153 local node, host = origin.username, origin.host;
154 local data = load_prefs(node, host);
155 if not data then
156 return false;
157 end
158 for i, child in ipairs(data) do
159 if child.name == "item" and child.attr["jid"] == elem.attr["jid"] then
160 table.remove(data, i)
161 break;
162 end
163 end
164 store_prefs(data, node, host);
165 origin.send(st.reply(stanza));
166 return true;
167 end
168
169 local function sessionremove_handler(event)
170 local origin, stanza = event.origin, event.stanza;
171 if stanza.attr.type ~= "set" then
172 return false;
173 end
174 local elem = stanza.tags[1].tags[1];
175 if not elem or elem.name ~= "session" then
176 return false;
177 end
178 local node, host = origin.username, origin.host;
179 local data = load_prefs(node, host);
180 if not data then
181 return false;
182 end
183 for i, child in ipairs(data) do
184 if child.name == "session" and child.attr["thread"] == elem.attr["thread"] then
185 table.remove(data, i)
186 break;
187 end
188 end
189 store_prefs(data, node, host);
190 origin.send(st.reply(stanza));
191 return true;
40 end 192 end
41 193
42 local function auto_handler(event) 194 local function auto_handler(event)
43 module:log("debug", "-- stanza:\n%s", tostring(event.stanza)); 195 -- event.origin.send(st.error_reply(event.stanza, "cancel", "feature-not-implemented"));
44 if event.stanza.attr.type == "set" then 196 local origin, stanza = event.origin, event.stanza;
45 event.origin.send(st.error_reply(event.stanza, "cancel", "feature-not-implemented")); 197 if stanza.attr.type ~= "set" then
46 return true; 198 return false;
47 end 199 end
200 local elem = stanza.tags[1];
201 local node, host = origin.username, origin.host;
202 local data = load_prefs(node, host);
203 if not data then
204 return false;
205 end
206 local setting = data:child_with_name(elem.name)
207 setting.attr["save"] = elem.attr["save"];
208 store_prefs(data, node, host);
209 origin.send(st.reply(stanza));
210 return true;
48 end 211 end
49 212
50 local function chat_handler(event) 213 local function chat_handler(event)
51 module:log("debug", "-- stanza:\n%s", tostring(event.stanza)); 214 module:log("debug", "-- stanza:\n%s", tostring(event.stanza));
52 return true; 215 return true;
53 end 216 end
54 217
55 local function itemremove_handler(event)
56 module:log("debug", "-- stanza:\n%s", tostring(event.stanza));
57 return true;
58 end
59
60 local function list_handler(event) 218 local function list_handler(event)
61 module:log("debug", "-- stanza:\n%s", tostring(event.stanza)); 219 module:log("debug", "-- stanza:\n%s", tostring(event.stanza));
62 return true; 220 return true;
63 end 221 end
64 222
81 module:log("debug", "-- stanza:\n%s", tostring(event.stanza)); 239 module:log("debug", "-- stanza:\n%s", tostring(event.stanza));
82 return true; 240 return true;
83 end 241 end
84 242
85 module:hook("iq/self/urn:xmpp:archive:pref", preferences_handler); 243 module:hook("iq/self/urn:xmpp:archive:pref", preferences_handler);
244 module:hook("iq/self/urn:xmpp:archive:itemremove", itemremove_handler);
245 module:hook("iq/self/urn:xmpp:archive:sessionremove", sessionremove_handler);
86 module:hook("iq/self/urn:xmpp:archive:auto", auto_handler); 246 module:hook("iq/self/urn:xmpp:archive:auto", auto_handler);
87 module:hook("iq/self/urn:xmpp:archive:chat", chat_handler); 247 -- module:hook("iq/self/urn:xmpp:archive:chat", chat_handler);
88 module:hook("iq/self/urn:xmpp:archive:itemremove", itemremove_handler);
89 module:hook("iq/self/urn:xmpp:archive:list", list_handler); 248 module:hook("iq/self/urn:xmpp:archive:list", list_handler);
90 module:hook("iq/self/urn:xmpp:archive:modified", modified_handler); 249 module:hook("iq/self/urn:xmpp:archive:modified", modified_handler);
91 module:hook("iq/self/urn:xmpp:archive:remove", remove_handler); 250 module:hook("iq/self/urn:xmpp:archive:remove", remove_handler);
92 module:hook("iq/self/urn:xmpp:archive:retrieve", retrieve_handler); 251 module:hook("iq/self/urn:xmpp:archive:retrieve", retrieve_handler);
93 module:hook("iq/self/urn:xmpp:archive:save", save_handler); 252 module:hook("iq/self/urn:xmpp:archive:save", save_handler);