diff options
-rw-r--r-- | blueprints/artikkel.lua | 10 | ||||
-rwxr-xr-x | lupin | 31 | ||||
-rwxr-xr-x | lupin.lua | 255 |
3 files changed, 245 insertions, 51 deletions
diff --git a/blueprints/artikkel.lua b/blueprints/artikkel.lua index 926f53c..eb59e62 100644 --- a/blueprints/artikkel.lua +++ b/blueprints/artikkel.lua @@ -7,12 +7,12 @@ end function artikkel.form(body, data) html.p() - form.label("Overskrift:") - form.text('overskrift', data.overskrift, 32) - form.orz('bilde', data.bilde or '') + html.label("Overskrift:") + html.text('overskrift', data.overskrift, 32) + html.orz('bilde', data.bilde or '') html.p() - form.textarea('tekst', body) - form.submit('Lagre') + html.textarea('tekst', body) + html.submit('Lagre') end return artikkel @@ -1,25 +1,30 @@ #!/usr/bin/env lua +posix = require 'posix' + require 'lupin' local env = false -local format = "purestrain" -local blueprints = "lupin" +local blueprints = "blueprints" +local format = "html" local mode = "full" -for i, opt in ipairs(arg) do - if opt == "-e" then env = true - elseif opt == "-f" then format = "form" - elseif opt == "-h" then format = "html" - elseif opt == "-l" then format = "purestrain" - elseif opt == "-s" then mode = "short" - elseif opt == "-t" then mode = "title" - - else blueprints = opt - end + +last = 1 +for opt, optarg, optind in posix.getopt(arg, "efhpstb:") do + last = optind + if opt == "e" then env = true end + if opt == "f" then format = "form" end + if opt == "h" then format = "html" end + if opt == "p" then format = "pure" end + if opt == "s" then mode = "short" end + if opt == "t" then mode = "title" end + if opt == "b" then blueprints = optarg end end lupin.loadblueprints(blueprints) -lupin.transform(format, env, mode) +for i = last, #arg do + lupin.transform(arg[i], format, env, mode) +end @@ -1,7 +1,72 @@ posix = require 'posix' +json = require 'json' +http = require 'lcurl' + +require 'tokyocabinet' require 'corz' -local function printf(...) print(string.format(...)) end +CACHE = "/home/bie/tmp.db" + +cache = tokyocabinet.bdbnew() + +function oembed(endpoint, id) + cache:open(CACHE, cache.OWRITER + cache.OREADER) + local url = endpoint .. id + local cached = cache:get(id) + if cached then + local data = json.decode(cached) + cache:close() + return data.html + end + + local body = "" + local result = http.easy{url=url, writefunction=function(s) + body = body .. s + end}:perform() + if result:getinfo(http.INFO_RESPONSE_CODE) == 200 then + cache:put(id, body) + cache:close() + local data = json.decode(body) + return data.html + else + return ("<b>Klarte ikke embedde %s :(</b>"):format(url) + end +end + +function twitter(id) + return oembed("https://publish.twitter.com/oembed?url=", id) +end + +function youtube(id) + return oembed("http://www.youtube.com/oembed?url=", id) +end + +function soundcloud(id) + return oembed("https://soundcloud.com/oembed?format=json&url=", id) +end + +function vimeo(id) + return oembed("https://developer.vimeo.com/apis/oembed.json?url=", id) +end + +function twitch(id) + return oembed("https://api.twitch.tv/v4/oembed?url=", id) +end + +function instagram(id) + return oembed("https://api.instagram.com/oembed?url=", id) +end + +function flickr(id) + return oembed("https://www.flickr.com/services/oembed?url=", id) +end + +function facebook(id) + return oembed("https://www.facebook.com/plugins/video/oembed.json?url=", id) +end + + +local function printf(...) io.write(string.format(...)) end local function setfenv(fn, env) local i = 1 @@ -15,76 +80,151 @@ local function setfenv(fn, env) elseif not name then break end - i = i + 1 end - return fn end local html = {} -function html.label(label) - printf("<label>%s</label>", label) +function html.print(...) + printf(...) end -function html.orz(k, v) - printf("<img class='orz' data-name=%s src='%s' data-uri='/orz/'>", k, v) - printf("<input name='%s' value='%s' type='hidden'>", k, v) +function html.tag(tag, options) + options = options or {} + local text = options.text; options.text = nil + printf("<%s", tag) + for k, v in pairs(options) do + if v and v ~= "" then + printf(" %s='%s'", k, v) + else + printf(" %s", k) + end + end + printf(">") + if text then + printf(text or "") + printf("</%s>", tag) + end + printf("\n") +end +function html.label(options) + options.text = options.text or error("no text") + html.tag("label", options) end -function html.date(k, v, s) - printf("<input type=date name=%s size=%s value='%s'>", k, s or 10, v or '') +function html.orz(options) + if options.inline then + html.tag("a", { class = 'orz', text = 'orz'}) + return + end + local n = options.name or "orz" + local v = options.value or "//:0" + local uri = options.uri or "/orz/" + html.tag('img', { class='orz', ['data-name']=n, src=v, ['data-uri']=uri}) + html.tag('input', { name=n, value=v, type='hidden'}) + html.tag('a', { class='orz', ['data-name']=n, ['data-uri']=uri, text='orz'}) +end +function html.infobox(options) + html.print("<ul class=infobox>") + options.terms = options.terms or {} + options.terms[''] = "" + -- table.insert(options.terms, "") + local n = options.name or "info[]" + for k, v in ipairs(options.values) do + html.print("<li>") + local term, fact = v:match("^(.-)%s*:%s*(.-)$") + html.select(n, options.terms, term) + html.tag('input', { name=n, value=fact}) + end + html.print("<li class=last>") + html.select(n, options.terms, "") + html.tag('input', { name=n }) + html.print("</ul>") end -function html.text(k, v, s) - printf("<input type=text name=%s size=%s value='%s'>", k, s or 18, v or '') +function html.date(options) + local n = options.name or "date" + local s = options.size or 10 + local v = options.value or "" + html.tag('input', { type='date', name=n, size=s, value=v}) end -function html.hidden(k, v) - printf("<input type=hidden name=%s value='%s'>", k, v) +function html.text(options) + local n = options.name or "text" + local s = options.size or 18 + local v = options.value or "" + html.tag("input", { type='text', name=n, size=s, value=v}) end -function html.textarea(k, v, r, c) - c = c or 72 - r = r or 16 - printf("<textarea name=%s cols=%s rows=%s>%s</textarea>", k, c, r, v or '') +function html.hidden(options) + local n = options.name or "hidden" + local v = options.value or "" + html.tag('input', { type='hidden', name=n, value=v}) end -function html.print(s) - printf("%s", s) +function html.textarea(options) + local n = options.name or "textarea" + local v = (options.value or ""):gsub("[\n]$", "") + local cols = options.cols or 72 + local rows = options.rows or 12 + html.tag('textarea', { name=n, cols=cols, rows=rows, text=v}) end function html.select(k, options, selected) local p = "" printf("<select name='%s'>", k) for k,v in pairs(options) do - if selected and selected == tostring(v) then + if selected and selected == tostring(k) then p = "selected " end - printf("<option %svalue='%s'>%s</option>", p, v, v) + printf("<option %svalue='%s'>%s</option>", p, k, v) p = "" end - print("</select>") + printf("</select>") end function html.submit(value) printf("<input type=submit value='%s'>", value) end -function html.p(...) - printf("<p>%s", ... or '') +function html.img(options) + html.tag('img', { src=options.src, alt=options.alt}) +end +function html.p(options) + html.tag("p", options) end function html.h1(...) printf("<h1>%s</h1>", ... or '') end +function html.h2(...) + printf("<h2>%s</h2>", ... or '') +end +function html.h3(...) + printf("<h3>%s</h3>", ... or '') +end +function html.marxup(raw) + corz.marxup(raw, io.output()) +end -help = { html = html, os = os, posix = posix, pairs = pairs } +help = { html = html, os = os, posix = posix, pairs = pairs, ipairs = ipairs } lupin = {} lupin.blueprints = {} lupin.blueprints.default = { - purestrain = function(body, data) + pure = function(body, data) print(data.title) if data.type ~= "default" then - printf("# type: %s", data.type) + printf("# type: %s\n", data.type) end data.title = nil data.type = nil print(body) for key, value in pairs(data) do - print(("# %s: %s"):format(key, value)) + if key == "info" then + local term + for i,v in ipairs(data.info) do + if i % 2 == 1 then + term = v + else + if #data.info >= i then print(("# info: %s: %s"):format(term, v)) end + end + end + else + print(("# %s: %s"):format(key, value)) + end end end, form = function(body, data) @@ -97,7 +237,7 @@ lupin.blueprints.default = { elseif data.mode == "full" then printf("<h1>%s</h1>", data.title) end - printf(corz.marxup(body, io.stdout)) + corz.marxup(body, io.output()) if not next(data) then return end print("<dl>") for key, value in pairs(data) do @@ -122,26 +262,40 @@ function lupin.loadblueprints(path) end end -function lupin.transform(format, env, mode) +function lupin.transform(path, format, env, mode) + if path ~= "-" then + io.input(path) + end + local raw, data = "", {} + data.info = {} if env then data.type = os.getenv("POST_type") or "default" data.title = os.getenv("POST_title") or "default" raw = os.getenv("POST_text") or "" + raw = raw:gsub("\r\n", "\n") + raw = raw:gsub("[\n]+$", "") raw = raw:match("(.-)%s*$") if lupin.blueprints[data.type] and lupin.blueprints[data.type].env then lupin.blueprints[data.type].env(data) end + if os.getenv("POST_info") then + for line in os.getenv("POST_info"):gmatch("[^\r\n]+") do + table.insert(data.info, line) + end + end else for line in io.lines() do if line:match("^#") then local key, value = line:match("^#%s*(.-):%s*(.+)") - if key and value then data[key] = value end + if key and value and key == "info" then table.insert(data.info, value) + elseif key and value then data[key] = value end else if not data.title then data.title = line else + line = line:gsub("[\r\n]*", "") raw = raw .. line .. "\n" end end @@ -150,8 +304,43 @@ function lupin.transform(format, env, mode) end data.mode = mode if data.mode == "short" then - raw = raw:match("[^\r\n]+") + raw = data.lead or raw:match("[^\r\n]+") end + if path ~= "-" then + local stat = posix.stat(path) + local pwd = posix.getpasswd(stat.uid) + data.author = pwd.name + data.group = posix.getgroup(stat.gid).name + + if posix.stat(pwd.dir .. "/portrait.jpg") then + data.portrait = ("/users/%s.jpg"):format(data.author) + end + + if posix.stat(pwd.dir .. "/.name") then + data.author = io.open(pwd.dir .. "/.name"):read("*l") + end + end + + if format == "later" then + data.raw = raw + data.text = function() + local f = io.tmpfile() + corz.marxup(data.raw, f) + f:seek("set") + local result = f:read("*a") + result = result:gsub("$%s*twitter:%s*(.-)\n", twitter) + result = result:gsub("$%s*youtube:%s*(.-)\n", youtube) + result = result:gsub("$%s*soundcloud:%s*(.-)\n", soundcloud) + result = result:gsub("$%s*twitch:%s*(.-)\n", twitch) + result = result:gsub("$%s*vimeo:%s*(.-)\n", vimeo) + result = result:gsub("$%s*instagram:%s*(.-)\n", instagram) + result = result:gsub("$%s*flickr:%s*(.-)\n", flickr) + result = result:gsub("$%s*facebook:%s*(.-)\n", facebook) + return result + end + return data + end + lupin.blueprints[data.type][format](raw, data) end |