💾 Archived View for gemini.conman.org › extensions › GLV-1 › handlers › blog.lua captured on 2021-12-03 at 14:04:38.
⬅️ Previous capture (2020-10-31)
-=-=-=-=-=-=-
-- *********************************************************************** -- -- Copyright 2020 by Sean Conner. -- -- This program is free software: you can redistribute it and/or modify it -- under the terms of the GNU General Public License as published by the -- Free Software Foundation, either version 3 of the License, or (at your -- option) any later version. -- -- This program is distributed in the hope that it will be useful, but -- WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -- Public License for more details. -- -- You should have received a copy of the GNU General Public License along -- with this program. If not, see <http://www.gnu.org/licenses/>. -- -- Comments, questions and criticisms can be sent to: sean@conman.org -- -- ======================================================================= -- -- Code to handle blog requests. -- -- *********************************************************************** -- luacheck: globals init handler -- luacheck: ignore 611 631 local syslog = require "org.conman.syslog" local date = require "org.conman.date" local url = require "org.conman.parsers.url.data" + require "org.conman.parsers.url.gopher" + require "org.conman.parsers.url" local io = require "io" local os = require "os" local string = require "string" local readfile = require "GLV-1.handlers.file" local html = require "org.conman.app.port70.handlers.blog.html" local uurl = require "GLV-1.url-util" -- "org.conman.app.port70.handlers.blog.url-util" local format = require "org.conman.app.GLV-1.handlers.blog.format" local blog = require "org.conman.app.mod_blog" local require = require local ipairs = ipairs local tonumber = tonumber _ENV = {} -- *********************************************************************** -- usage: init() -- desc: Intialize the handler module -- *********************************************************************** function init(conf) conf.blog = blog.init(conf.config) conf.url = url:match(conf.url) return true end -- *********************************************************************** function handler(config,_,_,match,ios) local first = blog.bookend("first") local last = blog.bookend("last") local port do if config.url.port == 1965 then port = "" else port = string.format(":%d",config.url.port) end end -- ---------------------------------------------------------------- local function affiliate(location) for _,aff in ipairs(config.blog.affiliate) do if location.scheme == aff.proto then return string.format(aff.link,location.path) end end return uurl.toa(location) end -- ---------------------------------------------------------------- local function xlat_links(when,links) for i,link in ipairs(links) do local u = url:match(link) if u.scheme then local ltxt = affiliate(u) ios:write(string.format("=> %s [%d] %s\n",ltxt,i,ltxt)) else local t = blog.tumbler.new(link,first,last) if t then local ltxt = config.url.path .. link ios:write(string.format("=> %s [%d] %s\n",ltxt,i,ltxt)) else if link:match "^/" then if link:find("/thisday",1,true) then local ltxt = config.url.path .. link:sub(2,-1) ios:write(string.format("=> %s [%d] %s\n",ltxt,i.ltxt)) else ios:write(string.format("[%d] %s%s\n",i,config.blog.url,link:sub(2,-1))) end else if link:find("parallel/",1,true) then ios:write(string.format("[%d] %s%s\n",i,config.blog.url,link)) else local filename = string.format( "%s%04d/%02d/%02d/%s", config.url.path, when.year, when.month, when.day, link ) ios:write(string.format("=> %s [%d] %s\n",filename,i,filename)) end end end end end end -- ---------------------------------------------------------------- local function display(tumbler) local function geminilink(entry) return string.format("gemini://%s%s/%s%04d/%02d/%02d.%d", config.url.host, port, config.url.path, entry.when.year, entry.when.month, entry.when.day, entry.when.part ) end for entry in blog.entries(tumbler) do local x = html(entry.body) local text,links = format(x) ios:write("# ",entry.title,"\n") if tumbler.range then ios:write("## ",os.date("%A, %B %d, %Y",os.time(tumbler.start)),"\n") ios:write("=> ",geminilink(entry),"\n\n") end ios:write(text) xlat_links(tumbler.start,links) ios:write("\n") end return 20 end -- ---------------------------------------------------------------- local function thisday(req) local month,day = req:match("^thisday/?(%d+)/(%d+)") if not month then local now = os.date("*t") month = now.month day = now.day else month = tonumber(month) day = tonumber(day) end local bytes = ios.__wbytes for year = first.year , last.year do local x = string.format("%04d/%02d/%02d",year,month,day) local tumbler = blog.tumbler.new(x,first,last) if tumbler then tumbler.range = true display(tumbler) end end if ios.__wbytes == bytes then ios:write("There are no entries for this date.\n") end return 20 end -- ---------------------------------------------------------------- -- If the request is empty, display the year menu -- ---------------------------------------------------------------- if match[2] == "" then ios:write("20 text/gmeini\r\n") for i = last.year , first.year , -1 do ios:write(string.format("=> %s%04d %04d\n",config.url.path,i,i)) end return 20 end -- ---------------------------------------------------------------- -- There's a tumbler. Parse and handle -- ---------------------------------------------------------------- local tumbler = blog.tumbler.new(match[2],first,last) if not tumbler then if match[2]:match "^thisday" then ios:write("20 text/gemini\r\n") return thisday(match[2]) else ios:write("51\r\n") return 51 end end if tumbler.redirect then ios:write(string.format("31 %s%s\r\n",config.url.path,blog.tumbler.canonical(tumbler))) return 31 end if tumbler.file and tumbler.filename ~= "" then local filename = blog.filename(tumbler) if filename:match("%.x%-html$") then local f,err = io.open(filename,"rb") if not f then syslog('error',"%s: %s",filename,err) ios:write("51\r\n") return 51 end ios:write("20 text/gemini\r\n") local text,links = format(html(f:read("a"))) ios:write(text) xlat_links(tumbler.start,links) f:close() return 20 else local conf = { file = blog.filename(tumbler) } readfile.init(conf) return readfile.handler(conf,_,_,_,ios) end elseif tumbler.range then ios:write("20 text/gemini\r\n") return display(tumbler) elseif tumbler.ustart == 'year' then local when = { year = tumbler.start.year , month = 1 , day = 1 } ios:write("20 text/gemini\r\n") for i = 1 , 12 do if tumbler.start.year == first.year and i >= first.month or tumbler.start.year == last.year and i <= last.month or tumbler.start.year > first.year and tumbler.start.year < last.year then when.month = i local d = os.time(when) ios:write(string.format("=> %s%04d/%02d %s\n",config.url.path,when.year,i,os.date("%B",d))) end end return 20 elseif tumbler.ustart == 'month' then ios:write("20 text/gemini\r\n") local entries for day = 1 , date.daysinmonth(tumbler.start) do tumbler.start.day = day local list = blog.day_titles(tumbler.start) if #list > 0 then entries = true ios:write(string.format("=> %s%04d/%02d/%02d %04d/%02d/%02d\n",config.url.path,tumbler.start.year,tumbler.start.month,day,tumbler.start.year,tumbler.start.month,tumbler.start.day)) for i,title in ipairs(list) do ios:write(string.format("=> %s%04d/%02d/%02d.%d %s\n",config.url.path,tumbler.start.year,tumbler.start.month,day,i,title)) end end end if not entries then ios:write("There are no entries this month\n") end return 20 elseif tumbler.ustart == 'day' then ios:write("20 text/gemini\r\n") local list = blog.day_titles(tumbler.start) for i,title in ipairs(list) do ios:write(string.format("=> %s%04d/%02d/%02d.%d %s\n",config.url.path,tumbler.start.year,tumbler.start.month,tumbler.start.day,i,title)) end return 20 else ios:write("20 text/gemini\r\n") return display(tumbler) end end -- *********************************************************************** return _ENV