--[[ 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()