comparison mod_webpresence/mod_webpresence.lua @ 1054:432dc4056114

mod_webpresence: added /xml and /json; Rewritten /html; A bit of refactoring;
author Vadim Misbakh-Soloviov <mva@mva.name>
date Fri, 07 Jun 2013 06:42:50 +0700
parents 1c9a3454eb43
children 9a1b3f0d0939
comparison
equal deleted inserted replaced
1053:cabbcc1997d9 1054:432dc4056114
1 module:depends("http"); 1 module:depends("http");
2 2
3 local jid_split = require "util.jid".prepped_split; 3 local jid_split = require "util.jid".prepped_split;
4 local b64 = require "util.encodings".base64.encode; 4 local b64 = require "util.encodings".base64.encode;
5 local sha1 = require "util.hashes".sha1; 5 local sha1 = require "util.hashes".sha1;
6 local stanza = require "util.stanza".stanza;
7 local json = require "util.json".encode_ordered;
6 8
7 local function require_resource(name) 9 local function require_resource(name)
8 local icon_path = module:get_option_string("presence_icons", "icons"); 10 local icon_path = module:get_option_string("presence_icons", "icons");
9 local f, err = module:load_resource(icon_path.."/"..name); 11 local f, err = module:load_resource(icon_path.."/"..name);
10 if f then 12 if f then
11 return f:read("*a"); 13 return f:read("*a");
12 end 14 end
13 module:log("warn", "Failed to open image file %s", icon_path..name); 15 module:log("warn", "Failed to open image file %s", icon_path..name);
14 return ""; 16 return "";
15 end 17 end
16 18
17 local statuses = { online = {}, away = {}, xa = {}, dnd = {}, chat = {}, offline = {} }; 19 local statuses = { online = {}, away = {}, xa = {}, dnd = {}, chat = {}, offline = {} };
18 --[[for status, _ in pairs(statuses) do
19 statuses[status].image = { status_code = 200, headers = { content_type = "image/png" },
20 body = require_resource("status_"..status..".png") };
21 statuses[status].text = { status_code = 200, headers = { content_type = "text/plain" },
22 body = status };
23 end]]
24 20
25 local function handle_request(event, path) 21 local function handle_request(event, path)
26 local status, message; 22 local status, message;
27 local jid, type = path:match("([^/]+)/?(.*)$"); 23 local jid, type = path:match("([^/]+)/?(.*)$");
28 if jid then 24 if jid then
29 local user, host = jid_split(jid); 25 local user, host = jid_split(jid);
30 if host and not user then 26 if host and not user then
31 user, host = host, event.request.headers.host; 27 user, host = host, event.request.headers.host;
32 if host then host = host:gsub(":%d+$", ""); end 28 if host then host = host:gsub(":%d+$", ""); end
33 end 29 end
34 if user and host then 30 if user and host then
35 local user_sessions = hosts[host] and hosts[host].sessions[user]; 31 local user_sessions = hosts[host] and hosts[host].sessions[user];
36 if user_sessions then 32 if user_sessions then
37 status = user_sessions.top_resources[1]; 33 status = user_sessions.top_resources[1];
38 if status and status.presence then 34 if status and status.presence then
39 message = status.presence:child_with_name("status"); 35 message = status.presence:child_with_name("status");
40 status = status.presence:child_with_name("show"); 36 status = status.presence:child_with_name("show");
41 if not status then 37 if not status then
42 status = "online"; 38 status = "online";
43 else 39 else
44 status = status:get_text(); 40 status = status:get_text();
45 end 41 end
46 if message then 42 if message then
47 message = message:get_text(); 43 message = message:get_text();
48 end 44 end
49 end 45 end
50 end 46 end
51 end 47 end
52 end 48 end
53 status = status or "offline"; 49 status = status or "offline";
54 if type == "" then type = "image" end; 50 if type == "" then type = "image" end;
55 if type == "image" then 51
56 statuses[status].image = { status_code = 200, headers = { content_type = "image/png" }, 52 statuses[status].image = function()
57 body = require_resource("status_"..status..".png") }; 53 return { status_code = 200, headers = { content_type = "image/png" },
58 elseif type == "html" then 54 body = require_resource("status_"..status..".png")
59 local jid_hash = sha1(jid, true); 55 };
60 statuses[status].html = { status_code = 200, headers = { content_type = "text/html" }, 56 end;
61 body = [[<div id="]]..jid_hash..[[_status" class="xmpp_status">]].. 57 statuses[status].html = function()
62 [[<img id="]]..jid_hash..[[_img" class="xmpp_status_image" ]].. 58 local jid_hash = sha1(jid, true);
63 [[src="data:image/png;base64,]].. 59 return { status_code = 200, headers = { content_type = "text/html" },
64 b64(require_resource("status_"..status..".png"))..[[">]].. 60 body = [[<!DOCTYPE html>]]..
65 [[<span id="]]..jid_hash..[[_name" ]].. 61 tostring(
66 [[class="xmpp_status_name">]]..status..[[</span>]].. 62 stanza("html")
67 (message and [[<span id="]]..jid_hash..[[_message" ]].. 63 :tag("head")
68 [[class="xmpp_status_message">]]..message..[[</span>]] or "").. 64 :tag("title"):text("XMPP Status Page for "..jid):up():up()
69 [[</div>]] }; 65 :tag("body")
70 elseif type == "text" then 66 :tag("div", { id = jid_hash.."_status", class = "xmpp_status" })
71 statuses[status].text = { status_code = 200, headers = { content_type = "text/plain" }, 67 :tag("img", { id = jid_hash.."_img", class = "xmpp_status_image xmpp_status_"..status,
72 body = status }; 68 src = "data:image/png;base64,"..b64(require_resource("status_"..status..".png")) }):up()
73 elseif type == "message" then 69 :tag("span", { id = jid_hash.."_status_name", class = "xmpp_status_name" })
74 statuses[status].message = { status_code = 200, headers = { content_type = "text/plain" }, 70 :text("\194\160"..status):up()
75 body = (message and message or "") }; 71 :tag("span", { id = jid_hash.."_status_message", class = "xmpp_status_message" })
76 end 72 :text(message and "\194\160"..message.."" or "")
77 return statuses[status][type]; 73 )
74 };
75 end;
76 statuses[status].text = function()
77 return { status_code = 200, headers = { content_type = "text/plain" },
78 body = status
79 };
80 end;
81 statuses[status].message = function()
82 return { status_code = 200, headers = { content_type = "text/plain" },
83 body = (message and message or "")
84 };
85 end;
86 statuses[status].json = function()
87 return { status_code = 200, headers = { content_type = "application/json" },
88 body = json({
89 jid = jid,
90 show = status,
91 status = (message and message or "null")
92 })
93 };
94 end;
95 statuses[status].xml = function()
96 return { status_code = 200, headers = { content_type = "application/xml" },
97 body = [[<?xml version="1.0" encoding="utf-8"?>]]..
98 tostring(
99 stanza("result")
100 :tag("jid"):text(jid):up()
101 :tag("show"):text(status):up()
102 :tag("status"):text(message)
103 )
104 };
105 end
106 return statuses[status][type]();
78 end 107 end
79 108
80 module:provides("http", { 109 module:provides("http", {
81 default_path = "/status"; 110 default_path = "/status";
82 route = { 111 route = {
83 ["GET /*"] = handle_request; 112 ["GET /*"] = handle_request;
84 }; 113 };
85 }); 114 });