# HG changeset patch # User Vadim Misbakh-Soloviov # Date 1370562170 -25200 # Node ID 432dc40561144d60ddd96e1561807f65e9ce0772 # Parent cabbcc1997d9c927eea5e42cbed4bd0a8eae53d8 mod_webpresence: added /xml and /json; Rewritten /html; A bit of refactoring; diff -r cabbcc1997d9 -r 432dc4056114 mod_webpresence/mod_webpresence.lua --- a/mod_webpresence/mod_webpresence.lua Thu Jun 06 15:52:36 2013 +0100 +++ b/mod_webpresence/mod_webpresence.lua Fri Jun 07 06:42:50 2013 +0700 @@ -3,83 +3,112 @@ local jid_split = require "util.jid".prepped_split; local b64 = require "util.encodings".base64.encode; local sha1 = require "util.hashes".sha1; +local stanza = require "util.stanza".stanza; +local json = require "util.json".encode_ordered; local function require_resource(name) - local icon_path = module:get_option_string("presence_icons", "icons"); - local f, err = module:load_resource(icon_path.."/"..name); - if f then - return f:read("*a"); - end - module:log("warn", "Failed to open image file %s", icon_path..name); - return ""; + local icon_path = module:get_option_string("presence_icons", "icons"); + local f, err = module:load_resource(icon_path.."/"..name); + if f then + return f:read("*a"); + end + module:log("warn", "Failed to open image file %s", icon_path..name); + return ""; end local statuses = { online = {}, away = {}, xa = {}, dnd = {}, chat = {}, offline = {} }; ---[[for status, _ in pairs(statuses) do - statuses[status].image = { status_code = 200, headers = { content_type = "image/png" }, - body = require_resource("status_"..status..".png") }; - statuses[status].text = { status_code = 200, headers = { content_type = "text/plain" }, - body = status }; -end]] local function handle_request(event, path) - local status, message; - local jid, type = path:match("([^/]+)/?(.*)$"); - if jid then - local user, host = jid_split(jid); - if host and not user then - user, host = host, event.request.headers.host; - if host then host = host:gsub(":%d+$", ""); end - end - if user and host then - local user_sessions = hosts[host] and hosts[host].sessions[user]; - if user_sessions then - status = user_sessions.top_resources[1]; - if status and status.presence then - message = status.presence:child_with_name("status"); - status = status.presence:child_with_name("show"); - if not status then - status = "online"; - else - status = status:get_text(); - end - if message then - message = message:get_text(); - end - end - end - end - end - status = status or "offline"; - if type == "" then type = "image" end; - if type == "image" then - statuses[status].image = { status_code = 200, headers = { content_type = "image/png" }, - body = require_resource("status_"..status..".png") }; - elseif type == "html" then - local jid_hash = sha1(jid, true); - statuses[status].html = { status_code = 200, headers = { content_type = "text/html" }, - body = [[
]].. - [[]].. - [[]]..status..[[]].. - (message and [[]]..message..[[]] or "").. - [[
]] }; - elseif type == "text" then - statuses[status].text = { status_code = 200, headers = { content_type = "text/plain" }, - body = status }; - elseif type == "message" then - statuses[status].message = { status_code = 200, headers = { content_type = "text/plain" }, - body = (message and message or "") }; - end - return statuses[status][type]; + local status, message; + local jid, type = path:match("([^/]+)/?(.*)$"); + if jid then + local user, host = jid_split(jid); + if host and not user then + user, host = host, event.request.headers.host; + if host then host = host:gsub(":%d+$", ""); end + end + if user and host then + local user_sessions = hosts[host] and hosts[host].sessions[user]; + if user_sessions then + status = user_sessions.top_resources[1]; + if status and status.presence then + message = status.presence:child_with_name("status"); + status = status.presence:child_with_name("show"); + if not status then + status = "online"; + else + status = status:get_text(); + end + if message then + message = message:get_text(); + end + end + end + end + end + status = status or "offline"; + if type == "" then type = "image" end; + + statuses[status].image = function() + return { status_code = 200, headers = { content_type = "image/png" }, + body = require_resource("status_"..status..".png") + }; + end; + statuses[status].html = function() + local jid_hash = sha1(jid, true); + return { status_code = 200, headers = { content_type = "text/html" }, + body = [[]].. + tostring( + stanza("html") + :tag("head") + :tag("title"):text("XMPP Status Page for "..jid):up():up() + :tag("body") + :tag("div", { id = jid_hash.."_status", class = "xmpp_status" }) + :tag("img", { id = jid_hash.."_img", class = "xmpp_status_image xmpp_status_"..status, + src = "data:image/png;base64,"..b64(require_resource("status_"..status..".png")) }):up() + :tag("span", { id = jid_hash.."_status_name", class = "xmpp_status_name" }) + :text("\194\160"..status):up() + :tag("span", { id = jid_hash.."_status_message", class = "xmpp_status_message" }) + :text(message and "\194\160"..message.."" or "") + ) + }; + end; + statuses[status].text = function() + return { status_code = 200, headers = { content_type = "text/plain" }, + body = status + }; + end; + statuses[status].message = function() + return { status_code = 200, headers = { content_type = "text/plain" }, + body = (message and message or "") + }; + end; + statuses[status].json = function() + return { status_code = 200, headers = { content_type = "application/json" }, + body = json({ + jid = jid, + show = status, + status = (message and message or "null") + }) + }; + end; + statuses[status].xml = function() + return { status_code = 200, headers = { content_type = "application/xml" }, + body = [[]].. + tostring( + stanza("result") + :tag("jid"):text(jid):up() + :tag("show"):text(status):up() + :tag("status"):text(message) + ) + }; + end + return statuses[status][type](); end module:provides("http", { - default_path = "/status"; - route = { - ["GET /*"] = handle_request; - }; + default_path = "/status"; + route = { + ["GET /*"] = handle_request; + }; });