Software /
code /
prosody-modules
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 |
parent | 847:1c9a3454eb43 |
child | 1495: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 }); |