184 lines
4.5 KiB
Lua
184 lines
4.5 KiB
Lua
local sql = require("lsqlite3")
|
|
|
|
local session = require("session")
|
|
local tags = require("tags")
|
|
local db = require("db")
|
|
local queries = require("queries")
|
|
local util = require("util")
|
|
local cache = require("cache")
|
|
local pages = require("pages")
|
|
local config = require("config")
|
|
|
|
local stmnt_read, stmnt_update_views, stmnt_comments
|
|
|
|
local oldconfigure = configure
|
|
function configure(...)
|
|
stmnt_read = assert(db.conn:prepare(queries.select_post))
|
|
stmnt_update_views = assert(db.conn:prepare(queries.update_views))
|
|
stmnt_comments = assert(db.conn:prepare(queries.select_comments))
|
|
return oldconfigure(...)
|
|
end
|
|
|
|
|
|
--[[
|
|
Increases a story's hit counter by 1
|
|
]]
|
|
local function add_view(storyid)
|
|
stmnt_update_views:bind_names{
|
|
id = storyid
|
|
}
|
|
local err = util.do_sql(stmnt_update_views)
|
|
assert(err == sql.DONE, "Failed to update view counter:"..tostring(err))
|
|
stmnt_update_views:reset()
|
|
end
|
|
|
|
--[[
|
|
Populates ps with story settings, returns true if story was found,
|
|
or nil if it wasn't
|
|
]]
|
|
local function populate_ps_story(req,ps)
|
|
--Make sure our story exists
|
|
stmnt_read:bind_names{
|
|
id = ps.storyid,
|
|
}
|
|
local err = util.do_sql(stmnt_read)
|
|
if err == sql.DONE then
|
|
--We got no story
|
|
stmnt_read:reset()
|
|
log(LOG_DEBUG,"No story with id:" .. ps.storyid)
|
|
return false
|
|
end
|
|
--If we've made it here, we have a story. Populate our settings
|
|
--with title, text, ect.
|
|
assert(err == sql.ROW)
|
|
local title, storytext, tauthor, isanon, authorname, views, unlisted, hash = unpack(
|
|
stmnt_read:get_values()
|
|
)
|
|
ps.unlisted = unlisted == 1
|
|
if ps.unlisted and hash ~= ps.hash then
|
|
log(LOG_DEBUG,"Tried to get story id:" .. ps.storyid .. " but it was unlisted and hash was incorrect.")
|
|
stmnt_read:reset()
|
|
return false
|
|
end
|
|
ps.title = title
|
|
ps.text = zlib.decompress(storytext)
|
|
ps.tauthor = tauthor
|
|
ps.isanon = isanon == 1
|
|
ps.author = authorname
|
|
ps.views = views
|
|
stmnt_read:reset()
|
|
--Tags
|
|
ps.tags = tags.get(ps.storyid)
|
|
return true
|
|
end
|
|
|
|
--[[
|
|
Get the comments for a story
|
|
]]
|
|
local function get_comments(req,ps)
|
|
stmnt_comments:bind_names{
|
|
id = ps.storyid
|
|
}
|
|
local comments = {}
|
|
for com_author, com_isanon, com_text in util.sql_rows(stmnt_comments) do
|
|
table.insert(comments,{
|
|
author = com_author,
|
|
isanon = com_isanon == 1, --int to boolean
|
|
text = com_text
|
|
})
|
|
end
|
|
return comments
|
|
end
|
|
|
|
local function read_get(req)
|
|
--Pages settings
|
|
local ps = {
|
|
domain = config.domain,
|
|
host = http_request_get_host(req),
|
|
path = http_request_get_path(req),
|
|
method = http_method_text(req),
|
|
extra_load = {
|
|
'<script src="/_js/bookmark.js"></script>'
|
|
}
|
|
}
|
|
local err
|
|
--Get our story id
|
|
assert(string.len(ps.path) > 0,"Tried to read 0-length story id")
|
|
ps.idp = string.sub(ps.path,2)--remove leading "/"
|
|
ps.storyid,err = util.decode_id(ps.idp)
|
|
if not ps.storyid then
|
|
local page = pages.error{
|
|
errcode = 400,
|
|
errcodemsg = "Bad Request",
|
|
explanation = string.format("Failed to find story id %q: %s",ps.path,err)
|
|
}
|
|
http_response(req,400,page)
|
|
return
|
|
end
|
|
|
|
add_view(ps.storyid)
|
|
|
|
--If we're logged in, set author and authorid
|
|
local author, authorid = session.get(req)
|
|
if author and authorid then
|
|
ps.loggedauthor = author
|
|
ps.iam = author
|
|
ps.loggedauthorid = authorid
|
|
end
|
|
|
|
--If we need to show comments
|
|
http_request_populate_qs(req)
|
|
ps.show_comments = http_argument_get_string(req,"comments")
|
|
if ps.show_comments then
|
|
ps.comments = get_comments(req,ps)
|
|
end
|
|
|
|
--If this post is unlisted, get the hash
|
|
local hashstr = http_argument_get_string(req,"pwd")
|
|
if hashstr then
|
|
ps.hash = util.decode_unlisted(hashstr)
|
|
ps.hashstr = hashstr
|
|
end
|
|
|
|
local text
|
|
--normal story display
|
|
if (not ps.loggedauthor) then
|
|
local params = {}
|
|
if ps.show_comments then
|
|
table.insert(params,"comments=1")
|
|
end
|
|
if ps.hash then
|
|
table.insert(params,"pwd=" .. hashstr)
|
|
end
|
|
local cachestrparts = {
|
|
ps.path,
|
|
}
|
|
if #params > 0 then
|
|
table.insert(cachestrparts,"?")
|
|
table.insert(cachestrparts,table.concat(params,"&"))
|
|
end
|
|
local cachestr = table.concat(cachestrparts)
|
|
text = cache.render(cachestr,function()
|
|
log(LOG_DEBUG,"Cache miss, rendering story " .. cachestr)
|
|
if not populate_ps_story(req,ps) then
|
|
return pages.nostory(ps)
|
|
end
|
|
local output = pages.read(ps)
|
|
assert(output,"failed to read page:" .. cachestr)
|
|
return output
|
|
end)
|
|
else --we are logged in, don't cache
|
|
if not populate_ps_story(req,ps) then
|
|
text = pages.nostory(ps)
|
|
else
|
|
ps.owner = (ps.loggedauthorid == ps.tauthor)
|
|
text = pages.read(ps)
|
|
end
|
|
end
|
|
assert(text)
|
|
http_response(req,200,text)
|
|
return
|
|
end
|
|
|
|
return read_get
|