Merge 0.10->trunk
[prosody.git] / plugins / mod_announce.lua
1 -- Prosody IM
2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
4 --
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
7 --
8
9 local st, jid = require "util.stanza", require "util.jid";
10
11 local hosts = prosody.hosts;
12 local is_admin = require "core.usermanager".is_admin;
13
14 function send_to_online(message, host)
15         local sessions;
16         if host then
17                 sessions = { [host] = hosts[host] };
18         else
19                 sessions = hosts;
20         end
21
22         local c = 0;
23         for hostname, host_session in pairs(sessions) do
24                 if host_session.sessions then
25                         message.attr.from = hostname;
26                         for username in pairs(host_session.sessions) do
27                                 c = c + 1;
28                                 message.attr.to = username.."@"..hostname;
29                                 module:send(message);
30                         end
31                 end
32         end
33
34         return c;
35 end
36
37
38 -- Old <message>-based jabberd-style announcement sending
39 function handle_announcement(event)
40         local origin, stanza = event.origin, event.stanza;
41         local node, host, resource = jid.split(stanza.attr.to);
42
43         if resource ~= "announce/online" then
44                 return; -- Not an announcement
45         end
46
47         if not is_admin(stanza.attr.from) then
48                 -- Not an admin? Not allowed!
49                 module:log("warn", "Non-admin '%s' tried to send server announcement", stanza.attr.from);
50                 return;
51         end
52
53         module:log("info", "Sending server announcement to all online users");
54         local message = st.clone(stanza);
55         message.attr.type = "headline";
56         message.attr.from = host;
57
58         local c = send_to_online(message, host);
59         module:log("info", "Announcement sent to %d online users", c);
60         return true;
61 end
62 module:hook("message/host", handle_announcement);
63
64 -- Ad-hoc command (XEP-0133)
65 local dataforms_new = require "util.dataforms".new;
66 local announce_layout = dataforms_new{
67         title = "Making an Announcement";
68         instructions = "Fill out this form to make an announcement to all\nactive users of this service.";
69
70         { name = "FORM_TYPE", type = "hidden", value = "http://jabber.org/protocol/admin" };
71         { name = "subject", type = "text-single", label = "Subject" };
72         { name = "announcement", type = "text-multi", required = true, label = "Announcement" };
73 };
74
75 function announce_handler(self, data, state)
76         if state then
77                 if data.action == "cancel" then
78                         return { status = "canceled" };
79                 end
80
81                 local fields = announce_layout:data(data.form);
82
83                 module:log("info", "Sending server announcement to all online users");
84                 local message = st.message({type = "headline"}, fields.announcement):up()
85                         :tag("subject"):text(fields.subject or "Announcement");
86
87                 local count = send_to_online(message, data.to);
88
89                 module:log("info", "Announcement sent to %d online users", count);
90                 return { status = "completed", info = ("Announcement sent to %d online users"):format(count) };
91         else
92                 return { status = "executing", actions = {"next", "complete", default = "complete"}, form = announce_layout }, "executing";
93         end
94
95         return true;
96 end
97
98 local adhoc_new = module:require "adhoc".new;
99 local announce_desc = adhoc_new("Send Announcement to Online Users", "http://jabber.org/protocol/admin#announce", announce_handler, "admin");
100 module:provides("adhoc", announce_desc);
101