smr/tools/archive/main.lua

110 lines
3.1 KiB
Lua

--[[
Implements extracting the database to an archive file, you probably want a cron
job for this.
# Generates the archive
lua tools/archive/main.lua
]]
local sql = require("lsqlite3")
local argparse = require("argparse")
local zlib = require("zlib")
local etlua = require("etlua")
local crc32 = require("tools.archive.crc32")
local parser = argparse(){
name = "tools/archive/main.lua",
description = "Generate a downloadable zip archive.",
epilog = "Other tools included in the smr source distribution include:accounts",
}
parser:help_max_width(80)
parser:option("-d --database","The database file","kore_chroot/data/posts.db")
parser:option("-o --output","Output to directory","kore_chroot/data/archive")
args = parser:parse()
local db,err,errmsg = sql.open(args.database, sql.OPEN_READWRITE)
local outfile = io.open(args.output,"w")
if not db then
error(string.format("Failed to open %s : %s",args.database,errmsg))
end
local index_f = assert(io.open("tools/archive/main.etlua"))
local index_tmpl = assert(index_f:read("*a"))
index_f:close()
local template_main = etlua.compile(index_tmpl)
local story_f = assert(io.open("tools/archive/story.etlua"))
story_tmpl = assert(story_f:read("*a"))
story_f:close()
local template_story = etlua.compile(story_tmpl)
local zipped_files = {}
for row in db:rows([[
SELECT
posts.id,
posts.post_text,
posts.post_title,
authors.name,
posts.isanon,
posts.post_time,
GROUP_CONCAT(tags.tag,";")
FROM posts, authors
LEFT JOIN tags ON tags.postid = posts.id
WHERE
posts.authorid = authors.id AND
posts.unlisted = 0
GROUP BY posts.id
ORDER BY posts.post_time
]]) do
local id, text, title, author, isanon, post_time, tags_txt = unpack(row)
local tags_txt = (tags_txt or "") .. ";"
local tags = {}
for tag in tags_txt:gmatch("([^;]+)") do
table.insert(tags,tag)
end
local story_txt = zlib.decompress(text)
local file_data = template_story{
text = story_txt,
author = isanon == 0 and author or "Anonymous",
title = title,
tags = tags,
}
local filename = string.format("s%d.html",id)
table.insert(zipped_files,{
filename = filename,
author = isanon == 0 and author or "Anonymous",
tags = tags,
title = title,
posted = os.date("%B %d %Y",tonumber(post_time)),
})
local fd = assert(io.open(args.output .. "/" .. filename,"w"))
assert(fd:write(file_data))
assert(fd:close())
end
--index.html
local index_txt = template_main{
stories = zipped_files,
}
local fd = assert(io.open(string.format("%s/index.html",args.output),"w"))
assert(fd:write(index_txt))
assert(fd:close())
--css
local cssfd = assert(io.open("assets/style.css","r"))
local csstxt = assert(cssfd:read("*a"))
assert(cssfd:close())
local fd = assert(io.open(string.format("%s/style.css",args.output),"w"))
assert(fd:write(csstxt))
assert(fd:close())
--remove the previous zip archive if it exists
local oldzipfd, err = io.open(args.output,"r")
if oldzipfd then
local rmfd = assert(io.popen(string.format("rm %s.zip",args.output),"r"))
assert(rmfd:read("*a"))
assert(rmfd:close())
end
local zipfd = assert(io.popen(string.format("zip -r -j %s %s",args.output, args.output),"r"))
assert(zipfd:read("*a"))
assert(zipfd:close())
db:close()