forked from mio/gemwriter
248 lines
6.9 KiB
Lua
248 lines
6.9 KiB
Lua
local conf = require("config")
|
|
local tpl = require("template")
|
|
local util = require("util")
|
|
|
|
|
|
local writer = {}
|
|
|
|
writer.app = {
|
|
exec_name = "gw",
|
|
last_updated = "2022-07-24",
|
|
name = "gemwriter",
|
|
version = "0.1",
|
|
}
|
|
|
|
writer.conf = {}
|
|
writer.defaults = {
|
|
atom_file = "atom.xml",
|
|
author = "Gem",
|
|
-- Atom feed date format
|
|
entry_date_format = "%Y-%m-%dT%X+00:00",
|
|
entry_ext = ".gmi",
|
|
entry_slug = os.date("%Y-%m-%d-%H%M%S"),
|
|
entry_file_pattern = "[%/](%d%d%d%d%-%d%d%-%d%d)(.*)[%.](%a*)",
|
|
gen_atom_feed = true,
|
|
gen_index_page = true,
|
|
index_file = "index.gmi",
|
|
page_slug = "untitled-" .. os.date("%Y%m%d%H%M%S"),
|
|
title = "gemlog",
|
|
subtitle = "a Gemini log",
|
|
url = "",
|
|
output_dir = "log",
|
|
rsync_exec = "/usr/bin/rsync",
|
|
rsync_options = "-avz",
|
|
rsync_remote = "",
|
|
}
|
|
|
|
writer.entries = {}
|
|
|
|
writer.msg = {
|
|
add_entry = "Created ",
|
|
help = writer.app.exec_name .. [[ [options] [slug]
|
|
|
|
Options:
|
|
|
|
page [slug] Add a new page with the given name
|
|
post [slug] Add a new entry with the given name
|
|
index Generate an index page and feed of entries
|
|
publish Index and copy posts to a remote server (requires rsync)
|
|
help Show this help message
|
|
version Print version info
|
|
]],
|
|
index = "Created index page and feed.",
|
|
publish = "Published log.",
|
|
}
|
|
|
|
|
|
function writer.load_config(config)
|
|
for k, v in pairs(writer.defaults) do
|
|
if config[k] == nil then
|
|
writer.conf[k] = writer.defaults[k]
|
|
else
|
|
writer.conf[k] = config[k]
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function writer.replace_vars(str, vars, vals)
|
|
local text = str
|
|
for k, v in pairs(vars) do
|
|
text = string.gsub(text, v, vals[k])
|
|
end
|
|
return text
|
|
end
|
|
|
|
|
|
function writer.add_entry(slug)
|
|
local text = tpl.log_gmi
|
|
text = string.gsub(text, tpl.vars.entry.date,
|
|
os.date(writer.conf.entry_date_format))
|
|
text = string.gsub(text, tpl.vars.entry.author, writer.conf.author)
|
|
|
|
local entry_name = slug .. writer.conf.entry_ext
|
|
os.execute("test -d " .. writer.conf.output_dir .. " || mkdir -p " ..
|
|
writer.conf.output_dir)
|
|
util.write_file(writer.conf.output_dir .. "/" .. entry_name, text)
|
|
end
|
|
|
|
|
|
function writer.get_entries()
|
|
local ls_cmd = io.popen("ls " .. writer.conf.output_dir .. " | grep " ..
|
|
writer.conf.entry_ext)
|
|
local ls = ls_cmd:read("*a")
|
|
local entries = {}
|
|
local n = 0
|
|
local files_list = util.split_str(ls)
|
|
for f = 1, #files_list do
|
|
if files_list[f] ~= writer.conf.index_file then
|
|
n = n + 1
|
|
entries[n] = { files_list[f], util.read_file(writer.conf.output_dir ..
|
|
"/" .. files_list[f]) }
|
|
end
|
|
end
|
|
return entries
|
|
end
|
|
|
|
|
|
function writer.get_entries_meta()
|
|
local meta = {}
|
|
local entries = writer.get_entries()
|
|
for e = 1, #entries do
|
|
meta[e] = {}
|
|
if string.find(entries[e][2], "# ") == nil then
|
|
meta[e]["title"] = entries[e][1]
|
|
meta[e]["content"] = entries[e][2]
|
|
else
|
|
meta[e]["title"] = util.extract_str(entries[e][2], "# ", "\n")
|
|
hi1, hi2 = string.find(entries[e][2], "# ")
|
|
meta[e]["content"] = string.sub(entries[e][2], hi1,
|
|
string.len(entries[e][2]))
|
|
end
|
|
if string.find(entries[e][2], "author: ") == nil then
|
|
meta[e]["author"] = writer.conf.author
|
|
else
|
|
meta[e]["author"] = util.extract_str(entries[e][2], "author: ", "\n")
|
|
end
|
|
if string.find(entries[e][2], "date: ") == nil then
|
|
meta[e]["date"] = util.extract_file_date(writer.conf.output_dir,
|
|
entries[e][1])
|
|
if (meta[e]["date"] == "") or (meta[e]["date"] == nil) then
|
|
meta[e]["date"] = os.date(writer.conf.entry_date_format)
|
|
end
|
|
else
|
|
meta[e]["date"] = util.extract_str(entries[e][2], "date: ", "\n")
|
|
end
|
|
if string.find(entries[e][2], "summary: ") == nil then
|
|
meta[e]["summary"] = meta[e]["title"]
|
|
else
|
|
meta[e]["summary"] = util.extract_str(entries[e][2], "summary: ", "\n")
|
|
end
|
|
if string.find(entries[e][2], "tags: ") == nil then
|
|
meta[e]["tags"] = ""
|
|
else
|
|
meta[e]["tags"] = util.extract_str(entries[e][2], "tags: ", "\n")
|
|
end
|
|
meta[e]["url"] = writer.conf.url .. "/" .. entries[e][1]
|
|
end
|
|
return meta
|
|
end
|
|
|
|
|
|
function writer.gen_index_page()
|
|
local index_text = writer.replace_vars(tpl.index_gmi, tpl.vars.log,
|
|
writer.conf)
|
|
local entries_text = ""
|
|
-- Reverse insert links to log entries, newest first
|
|
for e = #writer.entries, 1, -1 do
|
|
local entry_date = util.split_str(writer.entries[e]["date"], "(.*)[T]")[1]
|
|
-- Get entry filename from the url
|
|
local fi1, fi2 = string.find(writer.entries[e]["url"],
|
|
writer.conf.entry_file_pattern)
|
|
entries_text = entries_text .. "\n=> " ..
|
|
string.sub(writer.entries[e]["url"], fi1 + 1, fi2) .. " " ..
|
|
entry_date .. " " .. writer.entries[e]["title"]
|
|
end
|
|
index_text = string.gsub(index_text, tpl.vars.index.entries, entries_text)
|
|
util.write_file(writer.conf.output_dir .. "/" .. writer.conf.index_file,
|
|
index_text)
|
|
end
|
|
|
|
|
|
function writer.gen_atom_feed()
|
|
local feed_meta = {
|
|
date = os.date(writer.conf.entry_date_format),
|
|
url = writer.conf.url .. "/" .. writer.conf.atom_file,
|
|
}
|
|
local feed_text = writer.replace_vars(tpl.atom_header, tpl.vars.log,
|
|
writer.conf)
|
|
feed_text = writer.replace_vars(feed_text, tpl.vars.feed, feed_meta)
|
|
local feed_entry = ""
|
|
-- Reverse insert log entries, newest first
|
|
for e = #writer.entries, 1, -1 do
|
|
feed_entry = tpl.atom_entry
|
|
feed_entry = writer.replace_vars(feed_entry, tpl.vars.entry,
|
|
writer.entries[e])
|
|
feed_text = feed_text .. feed_entry
|
|
end
|
|
feed_text = feed_text .. tpl.atom_footer
|
|
util.write_file(writer.conf.output_dir .. "/" .. writer.conf.atom_file,
|
|
feed_text)
|
|
end
|
|
|
|
|
|
function writer.publish()
|
|
os.execute(writer.conf.rsync_exec .. " " .. writer.conf.rsync_options ..
|
|
" " .. writer.conf.output_dir .. " " .. writer.conf.rsync_remote)
|
|
end
|
|
|
|
|
|
|
|
local cli = {}
|
|
|
|
function cli.handle_args(args)
|
|
if (args[1] ~= "help") and (args[1] ~= "version") then
|
|
writer.load_config(conf)
|
|
end
|
|
|
|
if (args[1] == "index") or (args[1] == "publish") then
|
|
writer.entries = writer.get_entries_meta()
|
|
if writer.conf.gen_index_page then writer.gen_index_page() end
|
|
if writer.conf.gen_atom_feed then writer.gen_atom_feed() end
|
|
end
|
|
|
|
if args[1] == "post" then
|
|
local slug = args[2]
|
|
if slug == "" then
|
|
slug = writer.conf.entry_slug
|
|
else
|
|
slug = os.date("%Y-%m-%d") .. "-" .. slug
|
|
end
|
|
writer.add_entry(slug)
|
|
print(writer.msg.add_entry .. slug .. writer.conf.entry_ext)
|
|
|
|
elseif args[1] == "page" then
|
|
local slug = args[2]
|
|
if slug == "" then slug = writer.conf.page_slug end
|
|
writer.add_entry(slug)
|
|
print(writer.msg.add_entry .. slug .. writer.conf.entry_ext)
|
|
|
|
elseif args[1] == "index" then
|
|
print(writer.msg.index)
|
|
|
|
elseif args[1] == "publish" then
|
|
writer.publish()
|
|
print(writer.msg.publish)
|
|
|
|
elseif args[1] == "help" then
|
|
print(writer.msg.help)
|
|
|
|
elseif args[1] == "version" then
|
|
print(writer.app.name .. " " .. writer.app.version ..
|
|
" (" .. writer.app.last_updated .. ")")
|
|
end
|
|
end
|
|
|
|
|
|
cli.handle_args(arg)
|