Software /
code /
prosody-modules
Comparison
mod_archive_muc/mod_archive_muc.lua @ 237:d900be0dee3e
mod_archive: minor fix;
mod_archive_muc: added new module mod_archive_muc; init commit; workable, not fully tested.
author | shinysky<shinysky1986(AT)gmail.com> |
---|---|
date | Mon, 09 Aug 2010 18:45:51 +0800 |
child | 238:5343b3ebaffb |
comparison
equal
deleted
inserted
replaced
236:24582ea48471 | 237:d900be0dee3e |
---|---|
1 -- Prosody IM | |
2 -- Copyright (C) 2010 Dai Zhiwei | |
3 -- | |
4 -- This project is MIT/X11 licensed. Please see the | |
5 -- COPYING file in the source package for more information. | |
6 -- | |
7 | |
8 local st = require "util.stanza"; | |
9 local dm = require "util.datamanager"; | |
10 local jid = require "util.jid"; | |
11 local datetime = require "util.datetime"; | |
12 | |
13 local PREFS_DIR = "archive_muc_prefs"; | |
14 local ARCHIVE_DIR = "archive_muc"; | |
15 | |
16 local HOST = 'localhost'; | |
17 | |
18 local AUTO_ARCHIVING_ENABLED = true; | |
19 | |
20 module:add_feature("urn:xmpp:archive#preferences"); | |
21 module:add_feature("urn:xmpp:archive#management"); | |
22 | |
23 ------------------------------------------------------------ | |
24 -- Utils | |
25 ------------------------------------------------------------ | |
26 local function load_prefs(node, host) | |
27 return st.deserialize(dm.load(node, host, PREFS_DIR)); | |
28 end | |
29 | |
30 local function store_prefs(data, node, host) | |
31 dm.store(node, host, PREFS_DIR, st.preserialize(data)); | |
32 end | |
33 | |
34 local function date_time(localtime) | |
35 return datetime.datetime(localtime); | |
36 end | |
37 | |
38 local function match_jid(rule, id) | |
39 return not rule or jid.compare(id, rule); | |
40 end | |
41 | |
42 local function is_earlier(start, coll_start) | |
43 return not start or start <= coll_start; | |
44 end | |
45 | |
46 local function is_later(endtime, coll_start) | |
47 return not endtime or endtime >= coll_start; | |
48 end | |
49 | |
50 ------------------------------------------------------------ | |
51 -- Preferences | |
52 ------------------------------------------------------------ | |
53 local function preferences_handler(event) | |
54 local origin, stanza = event.origin, event.stanza; | |
55 module:log("debug", "-- Enter muc preferences_handler()"); | |
56 module:log("debug", "-- muc pref:\n%s", tostring(stanza)); | |
57 if stanza.attr.type == "get" then | |
58 local data = load_prefs(origin.username, origin.host); | |
59 if data then | |
60 origin.send(st.reply(stanza):add_child(data)); | |
61 else | |
62 origin.send(st.reply(stanza)); | |
63 end | |
64 elseif stanza.attr.type == "set" then | |
65 local node, host = origin.username, origin.host; | |
66 if stanza.tags[1] and stanza.tags[1].name == 'prefs' then | |
67 store_prefs(stanza.tags[1], node, host); | |
68 origin.send(st.reply(stanza)); | |
69 local user = bare_sessions[node.."@"..host]; | |
70 local push = st.iq({type="set"}); | |
71 push:add_child(stanza.tags[1]); | |
72 for _, res in pairs(user and user.sessions or NULL) do -- broadcast to all resources | |
73 if res.presence then -- to resource | |
74 push.attr.to = res.full_jid; | |
75 res.send(push); | |
76 end | |
77 end | |
78 end | |
79 end | |
80 return true; | |
81 end | |
82 | |
83 ------------------------------------------------------------ | |
84 -- Archive Management | |
85 ------------------------------------------------------------ | |
86 local function management_handler(event) | |
87 module:log("debug", "-- Enter muc management_handler()"); | |
88 local origin, stanza = event.origin, event.stanza; | |
89 local node, host = origin.username, origin.host; | |
90 local data = dm.list_load(node, host, ARCHIVE_DIR); | |
91 local elem = stanza.tags[1]; | |
92 local resset = {} | |
93 if data then | |
94 for i = #data, 1, -1 do | |
95 local forwarded = st.deserialize(data[i]); | |
96 local res = (match_jid(elem.attr["with"], forwarded.tags[2].attr.from) | |
97 or match_jid(elem.attr["with"], forwarded.tags[2].attr.to)) | |
98 and is_earlier(elem.attr["start"], forwarded.tags[1].attr["stamp"]) | |
99 and is_later(elem.attr["end"], forwarded.tags[1].attr["stamp"]); | |
100 if res then | |
101 table.insert(resset, forwarded); | |
102 end | |
103 end | |
104 for i = #resset, 1, -1 do | |
105 local res = st.message({to = stanza.attr.from, id=st.new_id()}); | |
106 res:add_child(resset[i]); | |
107 origin.send(res); | |
108 end | |
109 end | |
110 origin.send(st.reply(stanza)); | |
111 return true; | |
112 end | |
113 | |
114 ------------------------------------------------------------ | |
115 -- Message Handler | |
116 ------------------------------------------------------------ | |
117 local function is_in(list, jid) | |
118 for _,v in ipairs(list) do | |
119 if match_jid(v:get_text(), jid) then -- JID Matching | |
120 return true; | |
121 end | |
122 end | |
123 return false; | |
124 end | |
125 | |
126 local function is_in_roster(node, host, jid) | |
127 -- TODO | |
128 return true; | |
129 end | |
130 | |
131 local function apply_pref(node, host, jid) | |
132 local pref = load_prefs(node, host); | |
133 if not pref then | |
134 return AUTO_ARCHIVING_ENABLED; | |
135 end | |
136 local always = pref:child_with_name('always'); | |
137 if always and is_in(always, jid) then | |
138 return true; | |
139 end | |
140 local never = pref:child_with_name('never'); | |
141 if never and is_in(never, jid) then | |
142 return false; | |
143 end | |
144 local default = pref.attr['default']; | |
145 if default == 'roster' then | |
146 return is_in_roster(node, host, jid); | |
147 elseif default == 'always' then | |
148 return true; | |
149 elseif default == 'never' then | |
150 return false; | |
151 end | |
152 return AUTO_ARCHIVING_ENABLED; | |
153 end | |
154 | |
155 local function store_msg(msg, node, host) | |
156 local forwarded = st.stanza('forwarded', {xmlns='urn:xmpp:forward:tmp'}); | |
157 forwarded:tag('delay', {xmlns='urn:xmpp:delay',stamp=date_time()}):up(); | |
158 forwarded:add_child(msg); | |
159 dm.list_append(node, host, ARCHIVE_DIR, st.preserialize(forwarded)); | |
160 end | |
161 | |
162 local function msg_handler(data) | |
163 module:log("debug", "-- Enter muc msg_handler()"); | |
164 local origin, stanza = data.origin, data.stanza; | |
165 local body = stanza:child_with_name("body"); | |
166 if body then | |
167 local from_node, from_host = jid.split(stanza.attr.from); | |
168 local to_node, to_host = jid.split(stanza.attr.to); | |
169 -- FIXME only archive messages of users on this host | |
170 if from_host == HOST and apply_pref(from_node, from_host, stanza.attr.to) then | |
171 store_msg(stanza, from_node, from_host); | |
172 end | |
173 if to_host == HOST and apply_pref(to_node, to_host, stanza.attr.from) then | |
174 store_msg(stanza, to_node, to_host); | |
175 end | |
176 end | |
177 | |
178 return nil; | |
179 end | |
180 | |
181 -- Preferences | |
182 module:hook("iq/self/urn:xmpp:archive#preferences:prefs", preferences_handler); | |
183 -- Archive management | |
184 module:hook("iq/self/urn:xmpp:archive#management:query", management_handler); | |
185 | |
186 module:hook("message/full", msg_handler, 20); | |
187 module:hook("message/bare", msg_handler, 20); | |
188 | |
189 -- TODO prefs: [1] = "\n "; |