Changeset

301:b241c79a0eb7

mod_admin_web: Add a live view for C2S connections
author Florian Zeitz <florob@babelmonkeys.de>
date Mon, 27 Dec 2010 04:19:41 +0100
parents 300:b81e4f86a231
children 302:50abf9922e6e
files mod_admin_web/admin_web/mod_admin_web.lua mod_admin_web/admin_web/www_files/index.html mod_admin_web/admin_web/www_files/js/main.js mod_admin_web/admin_web/www_files/style.css
diffstat 4 files changed, 115 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/mod_admin_web/admin_web/mod_admin_web.lua	Sun Dec 26 19:05:39 2010 +0100
+++ b/mod_admin_web/admin_web/mod_admin_web.lua	Mon Dec 27 04:19:41 2010 +0100
@@ -4,6 +4,11 @@
 -- COPYING file in the source package for more information.
 --
 
+-- <session xmlns="http://prosody.im/streams/c2s" jid="alice@example.com/brussels">
+--   <encrypted/>
+--   <compressed/>
+-- </session>
+
 -- <session xmlns="http://prosody.im/streams/s2s" jid="example.com">
 --   <encrypted/>
 --   <compressed/>
@@ -22,7 +27,8 @@
 
 local http_base = (prosody.paths.plugins or "./plugins/") .. "admin_web/www_files";
 
-local xmlns_sessions = "http://prosody.im/streams/s2s";
+local xmlns_c2s_session = "http://prosody.im/streams/c2s";
+local xmlns_s2s_session = "http://prosody.im/streams/s2s";
 
 local response_400 = { status = "400 Bad Request", body = "<h1>Bad Request</h1>Sorry, we didn't understand your request :(" };
 local response_403 = { status = "403 Forbidden", body = "<h1>Forbidden</h1>You don't have permission to view the contents of this directory :(" };
@@ -37,6 +43,33 @@
 
 local idmap = {};
 
+function add_client(session)
+	local name = session.full_jid;
+	local id = idmap[name];
+	if not id then
+		id = uuid_generate();
+		idmap[name] = id;
+	end
+	local item = stanza.stanza("item", { id = id }):tag("session", {xmlns = xmlns_c2s_session, jid = name}):up();
+	if session.secure then
+		item:tag("encrypted"):up();
+	end
+	if session.compressed then
+		item:tag("compressed"):up();
+	end
+	hosts[service].modules.pubsub.service:publish(xmlns_c2s_session, service, id, item);
+	module:log("debug", "Added client " .. name);
+end
+
+function del_client(session)
+	local name = session.full_jid;
+	local id = idmap[name];
+	if id then
+		local notifier = stanza.stanza("retract", { id = id });
+		hosts[service].modules.pubsub.service:retract(xmlns_c2s_session, service, id, notifier);
+	end
+end
+
 function add_host(session, type)
 	local name = (type == "out" and session.to_host) or (type == "in" and session.from_host);
 	local id = idmap[name.."_"..type];
@@ -44,7 +77,7 @@
 		id = uuid_generate();
 		idmap[name.."_"..type] = id;
 	end
-	local item = stanza.stanza("item", { id = id }):tag("session", {xmlns = xmlns_sessions, jid = name})
+	local item = stanza.stanza("item", { id = id }):tag("session", {xmlns = xmlns_s2s_session, jid = name})
 		:tag(type):up();
 	if session.secure then
 		item:tag("encrypted"):up();
@@ -52,7 +85,7 @@
 	if session.compressed then
 		item:tag("compressed"):up();
 	end
-	hosts[service].modules.pubsub.service:publish(xmlns_sessions, service, id, item);
+	hosts[service].modules.pubsub.service:publish(xmlns_s2s_session, service, id, item);
 	module:log("debug", "Added host " .. name .. " s2s" .. type);
 end
 
@@ -61,7 +94,7 @@
 	local id = idmap[name.."_"..type];
 	if id then
 		local notifier = stanza.stanza("retract", { id = id });
-		hosts[service].modules.pubsub.service:retract(xmlns_sessions, service, id, notifier);
+		hosts[service].modules.pubsub.service:retract(xmlns_s2s_session, service, id, notifier);
 	end
 end
 
@@ -118,10 +151,10 @@
 	local host_session = prosody.hosts[host];
 	local http_conf = config.get("*", "core", "webadmin_http_ports");
 
-	if not select(2, hosts[service].modules.pubsub.service:get_nodes(service))[xmlns_sessions] then
-		local ok, errmsg = hosts[service].modules.pubsub.service:create(xmlns_sessions, service);
+	if not select(2, hosts[service].modules.pubsub.service:get_nodes(service))[xmlns_s2s_session] then
+		local ok, errmsg = hosts[service].modules.pubsub.service:create(xmlns_s2s_session, service);
 		if not ok then
-			error("Could not create node: " .. tostring(errmsg));
+			module:log("warn", "Could not create node " .. xmlns_s2s_session .. ": " .. tostring(errmsg));
 		end
 	end
 
@@ -136,9 +169,30 @@
 		end
 	end
 
+	if not select(2, hosts[service].modules.pubsub.service:get_nodes(service))[xmlns_c2s_session] then
+		local ok, errmsg = hosts[service].modules.pubsub.service:create(xmlns_c2s_session, service);
+		if not ok then
+			module:log("warn", "Could not create node " .. xmlns_c2s_session .. ": " .. tostring(errmsg));
+		end
+	end
+
+	for username, user in pairs(host_session.sessions or {}) do
+		for resource, session in pairs(user.sessions or {}) do
+			add_client(session);
+		end
+	end
+
 	httpserver.new_from_config(http_conf, handle_file_request, { base = "admin" });
 end
 
+module:hook("resource-bind", function(event)
+	add_client(event.session);
+end);
+
+module:hook("resource-unbind", function(event)
+	del_client(event.session);
+end);
+
 module:hook("s2sout-established", function(event)
 	add_host(event.session, "out");
 end);
--- a/mod_admin_web/admin_web/www_files/index.html	Sun Dec 26 19:05:39 2010 +0100
+++ b/mod_admin_web/admin_web/www_files/index.html	Mon Dec 27 04:19:41 2010 +0100
@@ -16,7 +16,8 @@
   <div id='menu'>
     <ul>
       <li id='adhocMenu'><a href="#">General</a></li>
-      <li id='serverMenu'><a href="#">Server</a></li>
+      <li id='serverMenu'><a href="#">Servers</a></li>
+      <li id='clientMenu'><a href="#">Clients</a></li>
     </ul>
   </div>
   <div id='login'>
@@ -46,6 +47,12 @@
       <ul id="s2sout"></ul>
     </div>
   </div>
+  <div id="c2sList">
+    <div class="container">
+      Client connections:
+      <ul id="c2s"></ul>
+    </div>
+  </div>
 </div>
 
 <div id='log_container'>
--- a/mod_admin_web/admin_web/www_files/js/main.js	Sun Dec 26 19:05:39 2010 +0100
+++ b/mod_admin_web/admin_web/www_files/js/main.js	Mon Dec 27 04:19:41 2010 +0100
@@ -1,6 +1,7 @@
 var BOSH_SERVICE = 'http://localhost:5280/http-bind/';
 var show_log = false;
 
+Strophe.addNamespace('C2SPUBSUB', 'http://prosody.im/streams/c2s');
 Strophe.addNamespace('S2SPUBSUB', 'http://prosody.im/streams/s2s');
 Strophe.addNamespace('PUBSUB', 'http://jabber.org/protocol/pubsub');
 Strophe.addNamespace('CAPS', 'http://jabber.org/protocol/caps');
@@ -43,6 +44,33 @@
     return true;
 }
 
+function _cbNewC2S(e) {
+    var items, retract, id, jid;
+    items = e.getElementsByTagName('item');
+    for (i = 0; i < items.length; i++) {
+        id = items[i].attributes['id'].value;
+        jid = items[i].getElementsByTagName('session')[0].attributes['jid'].value;
+        $('#c2s').append('<li id="' + id + '">' + jid + '</li>');
+    }
+    retract = e.getElementsByTagName('retract')[0];
+    if (retract) {
+        id = retract.attributes['id'].value;
+        $('#' + id).remove();
+    }
+    return true;
+}
+
+function _cbPubSub(e) {
+    var node = e.getElementsByTagName('items')[0].attributes['node'].value;
+    if (node == Strophe.NS.C2SPUBSUB) {
+        _cbNewC2S(e);
+    } else if (node == Strophe.NS.S2SPUBSUB) {
+        _cbNewS2S(e);
+    }
+
+    return true;
+}
+
 function onConnect(status) {
     if (status == Strophe.Status.CONNECTING) {
         log('Strophe is connecting.');
@@ -63,11 +91,16 @@
         log('Strophe is connected.');
         showDisconnect();
 	Adhoc.checkFeatures('#adhoc', connection.domain);
+        connection.addHandler(_cbPubSub, Strophe.NS.PUBSUB + '#event', 'message');
+        connection.send($iq({to: pubsubHost, type: 'set', id: connection.getUniqueId()}).c('pubsub', {xmlns: Strophe.NS.PUBSUB})
+                .c('subscribe', {node: Strophe.NS.C2SPUBSUB, jid: connection.jid}));
         connection.send($iq({to: pubsubHost, type: 'set', id: connection.getUniqueId()}).c('pubsub', {xmlns: Strophe.NS.PUBSUB})
                 .c('subscribe', {node: Strophe.NS.S2SPUBSUB, jid: connection.jid}));
-        connection.addHandler(_cbNewS2S, Strophe.NS.PUBSUB + '#event', 'message');
         connection.sendIQ($iq({to: pubsubHost, type: 'get', id: connection.getUniqueId()}).c('pubsub', {xmlns: Strophe.NS.PUBSUB})
                 .c('items', {node: Strophe.NS.S2SPUBSUB}), _cbNewS2S);
+        connection.sendIQ($iq({to: pubsubHost, type: 'get', id: connection.getUniqueId()}).c('pubsub', {xmlns: Strophe.NS.PUBSUB})
+                .c('items', {node: Strophe.NS.C2SPUBSUB}), _cbNewC2S);
+
     }
 }
 
@@ -82,6 +115,7 @@
     $('#menu').hide();
     $('#adhoc').hide();
     $('#s2sList').hide();
+    $('#c2sList').hide();
     $('#cred label').show();
     $('#cred br').show();
     $('ul').empty();
@@ -132,15 +166,25 @@
 
     $('#adhocMenu').click(function () {
 	$('#s2sList').slideUp();
+	$('#c2sList').slideUp();
 	$('#adhoc').slideDown();
         event.preventDefault();
     });
 
     $('#serverMenu').click(function () {
 	$('#adhoc').slideUp();
+	$('#c2sList').slideUp();
 	$('#s2sList').slideDown();
         event.preventDefault();
     });
+
+    $('#clientMenu').click(function () {
+	$('#adhoc').slideUp();
+	$('#s2sList').slideUp();
+	$('#c2sList').slideDown();
+        event.preventDefault();
+    });
+
 });
 
 window.onunload = window.onbeforeunload = function() {
--- a/mod_admin_web/admin_web/www_files/style.css	Sun Dec 26 19:05:39 2010 +0100
+++ b/mod_admin_web/admin_web/www_files/style.css	Mon Dec 27 04:19:41 2010 +0100
@@ -37,11 +37,7 @@
   color: #000000
 }
 
-#adhoc {
-  display: none
-}
-
-#s2sList {
+#adhoc, #s2sList, #c2sList {
   display: none
 }