Mercurial > prosody-modules
diff mod_http_index/mod_http_index.lua @ 1573:0d8cc6971cdb
mod_http_index: Generates an index of local HTTP apps
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Thu, 20 Nov 2014 14:48:46 +0100 |
parents | |
children | 1b5c817cb642 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_http_index/mod_http_index.lua Thu Nov 20 14:48:46 2014 +0100 @@ -0,0 +1,145 @@ +local st = require "util.stanza"; +local url = require"socket.url"; + +module:depends"http"; + +-- local dump = require"util.serialization".new"dump".serialize; + +local function template(data) + --[[ DOC + Like util.template, but deals with plain text + Returns a closure that is called with a table of values + {name} is substituted for values["name"] and is XML escaped + {name!} is substituted without XML escaping + {name?} is optional and is replaced with an empty string if no value exists + ]] + return function(values) + return (data:gsub("{([^}]-)(%p?)}", function (name, opt) + local value = values[name]; + if value then + if opt ~= "!" then + return st.xml_escape(value); + end + return value; + elseif opt == "?" then + return ""; + end + end)); + end +end + +-- TODO Move templates into files +local base = template(template[[ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<meta name="generator" value="prosody/{prosody_version} mod_{mod_name}"> +<link rel="canonical" href="{canonical}"> +<title>{title}</title> +<style> +body{background-color:#eeeeec;margin:1ex 0;padding-bottom:3em;font-family:Arial,Helvetica,sans-serif;} +header,footer{margin:1ex 1em;} +footer{font-size:smaller;color:#babdb6;} +.content{background-color:white;padding:1em;list-style-position:inside;} +nav{font-size:large;margin:1ex 1ex;clear:both;line-height:1.5em;} +nav a{padding: 1ex;text-decoration:none;} +nav a[rel="up"]{font-size:smaller;} +nav a[rel="prev"]{float:left;} +nav a[rel="next"]{float:right;} +nav a[rel="next::after"]{content:" →";} +nav a[rel="prev::before"]{content:"← ";} +nav a:empty::after,nav a:empty::before{content:""} +@media screen and (min-width: 460px) { +nav{font-size:x-large;margin:1ex 1em;} +} +a:link,a:visited{color:#2e3436;text-decoration:none;} +a:link:hover,a:visited:hover{color:#3465a4;} +ul,ol{padding:0;} +li{list-style:none;} +hr{visibility:hidden;clear:both;} +br{clear:both;} +li time{float:right;font-size:small;opacity:0.2;} +li:hover time{opacity:1;} +.room-list .description{font-size:smaller;} +q.body::before,q.body::after{content:"";} +.presence .verb{font-style:normal;color:#30c030;} +.presence.unavailable .verb{color:#c03030;} +</style> +</head> +<body> +<header> +<h1>{title}</h1> +{header!} +</header> +<hr> +<div class="content"> +{body!} +</div> +<hr> +<footer> +{footer!} +<br> +<div class="powered-by">Prosody {prosody_version?}</div> +</footer> +</body> +</html> +]] { prosody_version = prosody.version, mod_name = module.name }); + +local canonical = module:http_url(nil, "/"); +local page_template = template(base{ + canonical = canonical; + title = "HTTP stuff"; + header = ""; + body = [[ +<nav> +<ul> +{lines!} +</ul> +</nav> +]]; + footer = ""; +}); +local line_template = template[[ +<li><a href="{url}" title="{module}">{name}</a></li> +]]; + +local function relative(base, link) + base = url.parse(base); + link = url.parse(link); + for k,v in pairs(base) do + if link[k] == v then + link[k] = nil; + end + end + return url.build(link); +end + +local function handler(event) + local items = module:get_host_items("http-provider"); + local item; + for i = 1, #items do + item = items[i]; + if module.name ~= item._provided_by then + items[i] = line_template{ + name = item.name; + module = "mod_" .. item._provided_by; + url = relative(canonical, module:http_url(item.name, item.default_path)); + }; + else + items[i] = ""; + end + end + event.response.headers.content_type = "text/html"; + return page_template{ + lines = table.concat(items); + }; +end + +module:provides("http", { + route = { + ["GET /"] = handler; + }; + default_path = "/"; +});