-
Notifications
You must be signed in to change notification settings - Fork 0
/
mod_webpresence.lua
118 lines (110 loc) · 3.83 KB
/
mod_webpresence.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
module:depends("http");
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 "";
end
local statuses = { online = {}, away = {}, xa = {}, dnd = {}, chat = {}, offline = {} };
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";
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 = [[<!DOCTYPE html>]]..
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 = [[<?xml version="1.0" encoding="utf-8"?>]]..
tostring(
stanza("result")
:tag("jid"):text(jid):up()
:tag("show"):text(status):up()
:tag("status"):text(message)
)
};
end
if ((type == "") or (not statuses[status][type])) then
type = "image"
end;
return statuses[status][type]();
end
module:provides("http", {
default_path = "/status";
route = {
["GET /*"] = handle_request;
};
});