110 lines
3.1 KiB
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()
|