Software /
code /
prosody-modules
Annotate
mod_archive_muc/mod_archive_muc.lua @ 737:e4ea03b060ed
mod_archive: switch from/to
The XEP-0136 is not very explicit about the meening of <from> and <to>
elements, but the examples are clear: <from> means it comes from the user in
the 'with' attribute of the collection.
That is the opposite of what is currently implemented in that module.
So for better compatibility with complient clients, this switch the 'from' and
'to' fields
author | Olivier Goffart <ogoffart@woboq.com> |
---|---|
date | Wed, 04 Jul 2012 14:08:43 +0200 |
parent | 477:bbe4df968099 |
rev | line source |
---|---|
237 | 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"; | |
477
bbe4df968099
mod_archive_muc: A little refactoring to improve code search.
Waqas Hussain <waqas20@gmail.com>
parents:
476
diff
changeset
|
10 local jid_compare, jid_split, jid_bare = require "util.jid".compare, require "util.jid".bare, require "util.jid".split; |
bbe4df968099
mod_archive_muc: A little refactoring to improve code search.
Waqas Hussain <waqas20@gmail.com>
parents:
476
diff
changeset
|
11 local datetime = require "util.datetime".datetime; |
bbe4df968099
mod_archive_muc: A little refactoring to improve code search.
Waqas Hussain <waqas20@gmail.com>
parents:
476
diff
changeset
|
12 local user_exists = require "core.usermanager".user_exists; |
bbe4df968099
mod_archive_muc: A little refactoring to improve code search.
Waqas Hussain <waqas20@gmail.com>
parents:
476
diff
changeset
|
13 local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed; |
237 | 14 |
15 local PREFS_DIR = "archive_muc_prefs"; | |
16 local ARCHIVE_DIR = "archive_muc"; | |
17 | |
243
6202ce4d12d6
mod_archive: added some config options.
shinysky<shinysky1986(AT)gmail.com>
parents:
240
diff
changeset
|
18 local AUTO_MUC_ARCHIVING_ENABLED = module:get_option_boolean("auto_muc_archiving_enabled", true); |
237 | 19 |
476
2c85635318a5
mod_archive_muc: Fixed a nil global access.
Waqas Hussain <waqas20@gmail.com>
parents:
243
diff
changeset
|
20 local NULL = {}; |
2c85635318a5
mod_archive_muc: Fixed a nil global access.
Waqas Hussain <waqas20@gmail.com>
parents:
243
diff
changeset
|
21 |
237 | 22 module:add_feature("urn:xmpp:archive#preferences"); |
23 module:add_feature("urn:xmpp:archive#management"); | |
24 | |
25 ------------------------------------------------------------ | |
26 -- Utils | |
27 ------------------------------------------------------------ | |
240
ef0b580f434d
mod_archive_muc: clean up '\n ' in preference stanza
shinysky<shinysky1986(AT)gmail.com>
parents:
238
diff
changeset
|
28 local function trim(s) |
ef0b580f434d
mod_archive_muc: clean up '\n ' in preference stanza
shinysky<shinysky1986(AT)gmail.com>
parents:
238
diff
changeset
|
29 return (string.gsub(s, "^%s*(.-)%s*$", "%1")) |
ef0b580f434d
mod_archive_muc: clean up '\n ' in preference stanza
shinysky<shinysky1986(AT)gmail.com>
parents:
238
diff
changeset
|
30 end |
ef0b580f434d
mod_archive_muc: clean up '\n ' in preference stanza
shinysky<shinysky1986(AT)gmail.com>
parents:
238
diff
changeset
|
31 |
ef0b580f434d
mod_archive_muc: clean up '\n ' in preference stanza
shinysky<shinysky1986(AT)gmail.com>
parents:
238
diff
changeset
|
32 local function clean_up(t) |
ef0b580f434d
mod_archive_muc: clean up '\n ' in preference stanza
shinysky<shinysky1986(AT)gmail.com>
parents:
238
diff
changeset
|
33 for i = #t, 1, -1 do |
ef0b580f434d
mod_archive_muc: clean up '\n ' in preference stanza
shinysky<shinysky1986(AT)gmail.com>
parents:
238
diff
changeset
|
34 if type(t[i]) == 'table' then |
ef0b580f434d
mod_archive_muc: clean up '\n ' in preference stanza
shinysky<shinysky1986(AT)gmail.com>
parents:
238
diff
changeset
|
35 clean_up(t[i]); |
ef0b580f434d
mod_archive_muc: clean up '\n ' in preference stanza
shinysky<shinysky1986(AT)gmail.com>
parents:
238
diff
changeset
|
36 elseif type(t[i]) == 'string' and trim(t[i]) == '' then |
ef0b580f434d
mod_archive_muc: clean up '\n ' in preference stanza
shinysky<shinysky1986(AT)gmail.com>
parents:
238
diff
changeset
|
37 table.remove(t, i); |
ef0b580f434d
mod_archive_muc: clean up '\n ' in preference stanza
shinysky<shinysky1986(AT)gmail.com>
parents:
238
diff
changeset
|
38 end |
ef0b580f434d
mod_archive_muc: clean up '\n ' in preference stanza
shinysky<shinysky1986(AT)gmail.com>
parents:
238
diff
changeset
|
39 end |
ef0b580f434d
mod_archive_muc: clean up '\n ' in preference stanza
shinysky<shinysky1986(AT)gmail.com>
parents:
238
diff
changeset
|
40 end |
ef0b580f434d
mod_archive_muc: clean up '\n ' in preference stanza
shinysky<shinysky1986(AT)gmail.com>
parents:
238
diff
changeset
|
41 |
237 | 42 local function load_prefs(node, host) |
43 return st.deserialize(dm.load(node, host, PREFS_DIR)); | |
44 end | |
45 | |
46 local function store_prefs(data, node, host) | |
240
ef0b580f434d
mod_archive_muc: clean up '\n ' in preference stanza
shinysky<shinysky1986(AT)gmail.com>
parents:
238
diff
changeset
|
47 clean_up(data); |
237 | 48 dm.store(node, host, PREFS_DIR, st.preserialize(data)); |
49 end | |
50 | |
51 local function match_jid(rule, id) | |
477
bbe4df968099
mod_archive_muc: A little refactoring to improve code search.
Waqas Hussain <waqas20@gmail.com>
parents:
476
diff
changeset
|
52 return not rule or jid_compare(id, rule); |
237 | 53 end |
54 | |
55 local function is_earlier(start, coll_start) | |
56 return not start or start <= coll_start; | |
57 end | |
58 | |
59 local function is_later(endtime, coll_start) | |
60 return not endtime or endtime >= coll_start; | |
61 end | |
62 | |
63 ------------------------------------------------------------ | |
64 -- Preferences | |
65 ------------------------------------------------------------ | |
66 local function preferences_handler(event) | |
67 local origin, stanza = event.origin, event.stanza; | |
68 module:log("debug", "-- Enter muc preferences_handler()"); | |
69 module:log("debug", "-- muc pref:\n%s", tostring(stanza)); | |
70 if stanza.attr.type == "get" then | |
71 local data = load_prefs(origin.username, origin.host); | |
72 if data then | |
73 origin.send(st.reply(stanza):add_child(data)); | |
74 else | |
75 origin.send(st.reply(stanza)); | |
76 end | |
77 elseif stanza.attr.type == "set" then | |
78 local node, host = origin.username, origin.host; | |
79 if stanza.tags[1] and stanza.tags[1].name == 'prefs' then | |
80 store_prefs(stanza.tags[1], node, host); | |
81 origin.send(st.reply(stanza)); | |
82 local user = bare_sessions[node.."@"..host]; | |
83 local push = st.iq({type="set"}); | |
84 push:add_child(stanza.tags[1]); | |
85 for _, res in pairs(user and user.sessions or NULL) do -- broadcast to all resources | |
86 if res.presence then -- to resource | |
87 push.attr.to = res.full_jid; | |
88 res.send(push); | |
89 end | |
90 end | |
91 end | |
92 end | |
93 return true; | |
94 end | |
95 | |
96 ------------------------------------------------------------ | |
97 -- Archive Management | |
98 ------------------------------------------------------------ | |
99 local function management_handler(event) | |
100 module:log("debug", "-- Enter muc management_handler()"); | |
101 local origin, stanza = event.origin, event.stanza; | |
102 local node, host = origin.username, origin.host; | |
103 local data = dm.list_load(node, host, ARCHIVE_DIR); | |
104 local elem = stanza.tags[1]; | |
105 local resset = {} | |
106 if data then | |
107 for i = #data, 1, -1 do | |
108 local forwarded = st.deserialize(data[i]); | |
109 local res = (match_jid(elem.attr["with"], forwarded.tags[2].attr.from) | |
110 or match_jid(elem.attr["with"], forwarded.tags[2].attr.to)) | |
111 and is_earlier(elem.attr["start"], forwarded.tags[1].attr["stamp"]) | |
112 and is_later(elem.attr["end"], forwarded.tags[1].attr["stamp"]); | |
113 if res then | |
114 table.insert(resset, forwarded); | |
115 end | |
116 end | |
117 for i = #resset, 1, -1 do | |
118 local res = st.message({to = stanza.attr.from, id=st.new_id()}); | |
119 res:add_child(resset[i]); | |
120 origin.send(res); | |
121 end | |
122 end | |
123 origin.send(st.reply(stanza)); | |
124 return true; | |
125 end | |
126 | |
127 ------------------------------------------------------------ | |
128 -- Message Handler | |
129 ------------------------------------------------------------ | |
130 local function is_in(list, jid) | |
131 for _,v in ipairs(list) do | |
132 if match_jid(v:get_text(), jid) then -- JID Matching | |
133 return true; | |
134 end | |
135 end | |
136 return false; | |
137 end | |
138 | |
139 local function apply_pref(node, host, jid) | |
140 local pref = load_prefs(node, host); | |
141 if not pref then | |
243
6202ce4d12d6
mod_archive: added some config options.
shinysky<shinysky1986(AT)gmail.com>
parents:
240
diff
changeset
|
142 return AUTO_MUC_ARCHIVING_ENABLED; |
237 | 143 end |
144 local always = pref:child_with_name('always'); | |
145 if always and is_in(always, jid) then | |
146 return true; | |
147 end | |
148 local never = pref:child_with_name('never'); | |
149 if never and is_in(never, jid) then | |
150 return false; | |
151 end | |
152 local default = pref.attr['default']; | |
153 if default == 'roster' then | |
477
bbe4df968099
mod_archive_muc: A little refactoring to improve code search.
Waqas Hussain <waqas20@gmail.com>
parents:
476
diff
changeset
|
154 return is_contact_subscribed(node, host, jid_bare(jid)); |
237 | 155 elseif default == 'always' then |
156 return true; | |
157 elseif default == 'never' then | |
158 return false; | |
159 end | |
243
6202ce4d12d6
mod_archive: added some config options.
shinysky<shinysky1986(AT)gmail.com>
parents:
240
diff
changeset
|
160 return AUTO_MUC_ARCHIVING_ENABLED; |
237 | 161 end |
162 | |
163 local function store_msg(msg, node, host) | |
164 local forwarded = st.stanza('forwarded', {xmlns='urn:xmpp:forward:tmp'}); | |
477
bbe4df968099
mod_archive_muc: A little refactoring to improve code search.
Waqas Hussain <waqas20@gmail.com>
parents:
476
diff
changeset
|
165 forwarded:tag('delay', {xmlns='urn:xmpp:delay',stamp=datetime()}):up(); |
237 | 166 forwarded:add_child(msg); |
167 dm.list_append(node, host, ARCHIVE_DIR, st.preserialize(forwarded)); | |
168 end | |
169 | |
170 local function msg_handler(data) | |
171 module:log("debug", "-- Enter muc msg_handler()"); | |
172 local origin, stanza = data.origin, data.stanza; | |
173 local body = stanza:child_with_name("body"); | |
174 if body then | |
477
bbe4df968099
mod_archive_muc: A little refactoring to improve code search.
Waqas Hussain <waqas20@gmail.com>
parents:
476
diff
changeset
|
175 local from_node, from_host = jid_split(stanza.attr.from); |
bbe4df968099
mod_archive_muc: A little refactoring to improve code search.
Waqas Hussain <waqas20@gmail.com>
parents:
476
diff
changeset
|
176 local to_node, to_host = jid_split(stanza.attr.to); |
bbe4df968099
mod_archive_muc: A little refactoring to improve code search.
Waqas Hussain <waqas20@gmail.com>
parents:
476
diff
changeset
|
177 if user_exists(from_node, from_host) and apply_pref(from_node, from_host, stanza.attr.to) then |
237 | 178 store_msg(stanza, from_node, from_host); |
179 end | |
477
bbe4df968099
mod_archive_muc: A little refactoring to improve code search.
Waqas Hussain <waqas20@gmail.com>
parents:
476
diff
changeset
|
180 if user_exists(to_node, to_host) and apply_pref(to_node, to_host, stanza.attr.from) then |
237 | 181 store_msg(stanza, to_node, to_host); |
182 end | |
183 end | |
184 | |
185 return nil; | |
186 end | |
187 | |
188 -- Preferences | |
189 module:hook("iq/self/urn:xmpp:archive#preferences:prefs", preferences_handler); | |
190 -- Archive management | |
191 module:hook("iq/self/urn:xmpp:archive#management:query", management_handler); | |
192 | |
193 module:hook("message/bare", msg_handler, 20); | |
194 |