Get started on author biography.
Get started on implementing author biographies, add endpoints.
This commit is contained in:
parent
f5c729bfde
commit
d5ec6d6864
|
@ -16,6 +16,11 @@ describe("smr type checking",function()
|
||||||
types.number(t)
|
types.number(t)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
it("should check multiple types passed as arugments", function()
|
||||||
|
local types = require("types")
|
||||||
|
local num, tbl = 5, {}
|
||||||
|
types.check(num, types.number, nil)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
function assertf(bool, ...)
|
||||||
|
if bool then return end
|
||||||
|
local args = {...}
|
||||||
|
local assertmsg = args[1] or "Assetion failed"
|
||||||
|
table.remove(args,1)
|
||||||
|
error(string.format(assertmsg, table.unpack(args)),2)
|
||||||
|
end
|
|
@ -0,0 +1,69 @@
|
||||||
|
local zlib = require("zlib")
|
||||||
|
local sql = require("lsqlite3")
|
||||||
|
|
||||||
|
local db = require("db")
|
||||||
|
local queries = require("queries")
|
||||||
|
local util = require("util")
|
||||||
|
local pages = require("pages")
|
||||||
|
local tags = require("tags")
|
||||||
|
local session = require("session")
|
||||||
|
local config = require("config")
|
||||||
|
|
||||||
|
local stmnt_bio
|
||||||
|
local oldconfigure = configure
|
||||||
|
function configure(...)
|
||||||
|
stmnt_bio = assert(db.conn:prepare(queries.select_bio))
|
||||||
|
return oldconfigure(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function bio_edit_get(req)
|
||||||
|
local host = http_request_get_host(req)
|
||||||
|
local path = http_request_get_path(req)
|
||||||
|
local author, authorid = session.get(req)
|
||||||
|
|
||||||
|
http_request_populate_qs(req)
|
||||||
|
local ret
|
||||||
|
|
||||||
|
if (not author) or (not authorid) then
|
||||||
|
ret = pages.error{
|
||||||
|
errcode = 401,
|
||||||
|
errcodemsg = "Not authorized",
|
||||||
|
explanation = "You must be logged in to edit your biography."
|
||||||
|
}
|
||||||
|
http_response(req,400,ret)
|
||||||
|
end
|
||||||
|
|
||||||
|
--Get the logged in author's bio to display
|
||||||
|
stmnt_bio:bind_names{
|
||||||
|
authorid = authorid
|
||||||
|
}
|
||||||
|
local err = util.do_sql(stmnt_edit)
|
||||||
|
if err == sql.DONE then
|
||||||
|
--No rows, we're logged in but an author with our id doesn't
|
||||||
|
--exist? Something has gone wrong.
|
||||||
|
ret = pages.error{
|
||||||
|
errcode = 500,
|
||||||
|
errcodemsg = "Server error",
|
||||||
|
explanation = string.format([[
|
||||||
|
Tried to get the biography of author %q (%d) but no author with that id was
|
||||||
|
found, please report this error.
|
||||||
|
]], author, authorid),
|
||||||
|
should_traceback=true
|
||||||
|
}
|
||||||
|
stmnt_bio:reset()
|
||||||
|
http_response(req,500,ret)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
assert(err == sql.ROW)
|
||||||
|
local data = stmnt_bio:get_values()
|
||||||
|
local bio = unpack(data)
|
||||||
|
stmnt_bio:reset()
|
||||||
|
ret = pages.edit_bio{
|
||||||
|
text = bio,
|
||||||
|
user = author,
|
||||||
|
domain = config.domain,
|
||||||
|
}
|
||||||
|
http_response(req,200,ret)
|
||||||
|
end
|
||||||
|
|
||||||
|
return edit_get
|
|
@ -0,0 +1,108 @@
|
||||||
|
|
||||||
|
local sql = require("lsqlite3")
|
||||||
|
local zlib = require("zlib")
|
||||||
|
|
||||||
|
local db = require("db")
|
||||||
|
local queries = require("queries")
|
||||||
|
local pages = require("pages")
|
||||||
|
local parsers = require("parsers")
|
||||||
|
local util = require("util")
|
||||||
|
local tagslib = require("tags")
|
||||||
|
local cache = require("cache")
|
||||||
|
local config = require("config")
|
||||||
|
local session = require("session")
|
||||||
|
|
||||||
|
local stmnt_update_bio
|
||||||
|
|
||||||
|
local oldconfigure = configure
|
||||||
|
function configure(...)
|
||||||
|
stmnt_update_bio = assert(db.conn:prepare(queries.update_bio))
|
||||||
|
return oldconfigure(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function edit_post(req)
|
||||||
|
local host = http_request_get_host(req)
|
||||||
|
local path = http_request_get_path(req)
|
||||||
|
local author, author_id = session.get(req)
|
||||||
|
|
||||||
|
http_request_populate_post(req)
|
||||||
|
local storyid = tonumber(assert(http_argument_get_string(req,"story")))
|
||||||
|
local title = assert(http_argument_get_string(req,"title"))
|
||||||
|
local text = assert(http_argument_get_string(req,"text"))
|
||||||
|
local pasteas = assert(http_argument_get_string(req,"pasteas"))
|
||||||
|
local markup = assert(http_argument_get_string(req,"markup"))
|
||||||
|
local unlisted = http_argument_get_string(req,"unlisted") == "on"
|
||||||
|
local tags_str = http_argument_get_string(req,"tags")
|
||||||
|
stmnt_author_of:bind_names{
|
||||||
|
id = storyid
|
||||||
|
}
|
||||||
|
local err = util.do_sql(stmnt_author_of)
|
||||||
|
if err ~= sql.ROW then
|
||||||
|
stmnt_author_of:reset()
|
||||||
|
local msg = string.format("No author found for story: %d", storyid)
|
||||||
|
log(LOG_ERR,msg)
|
||||||
|
local response = pages.error{
|
||||||
|
errcode = 404,
|
||||||
|
errcodemsg = "Not Found",
|
||||||
|
explanation = msg,
|
||||||
|
should_traceback = true,
|
||||||
|
}
|
||||||
|
http_response(req,404,response)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local data = stmnt_author_of:get_values()
|
||||||
|
stmnt_author_of:reset()
|
||||||
|
local realauthor = data[1]
|
||||||
|
assert(realauthor == author_id) --Make sure the author of the story is the currently logged in user
|
||||||
|
local parsed = parsers[markup](text)
|
||||||
|
local compr_raw = zlib.compress(text)
|
||||||
|
local compr = zlib.compress(parsed)
|
||||||
|
local tags = {}
|
||||||
|
if tags_str then
|
||||||
|
tags = util.parse_tags(tags_str)
|
||||||
|
end
|
||||||
|
assert(stmnt_update_raw:bind_blob(1,compr_raw) == sql.OK)
|
||||||
|
assert(stmnt_update_raw:bind(2,markup) == sql.OK)
|
||||||
|
assert(stmnt_update_raw:bind(3,storyid) == sql.OK)
|
||||||
|
assert(util.do_sql(stmnt_update_raw) == sql.DONE, "Failed to update raw")
|
||||||
|
stmnt_update_raw:reset()
|
||||||
|
assert(stmnt_update:bind(1,title) == sql.OK)
|
||||||
|
assert(stmnt_update:bind_blob(2,compr) == sql.OK)
|
||||||
|
assert(stmnt_update:bind(3,pasteas == "anonymous" and 1 or 0) == sql.OK)
|
||||||
|
assert(stmnt_update:bind(4,unlisted) == sql.OK)
|
||||||
|
assert(stmnt_update:bind(5,storyid) == sql.OK)
|
||||||
|
assert(util.do_sql(stmnt_update) == sql.DONE, "Failed to update text")
|
||||||
|
stmnt_update:reset()
|
||||||
|
tagslib.set(storyid,tags)
|
||||||
|
local id_enc = util.encode_id(storyid)
|
||||||
|
local hash
|
||||||
|
local loc = string.format("https://%s/%s",config.domain,id_enc)
|
||||||
|
if unlisted then
|
||||||
|
stmnt_hash:bind_names{id=storyid}
|
||||||
|
local err = util.do_sql(stmnt_hash)
|
||||||
|
if err ~= sql.ROW then
|
||||||
|
error("Failed to get a post's hash while trying to make it unlisted")
|
||||||
|
end
|
||||||
|
local hash = stmnt_hash:get_value(0)
|
||||||
|
-- TODO: Remove this
|
||||||
|
-- Posts added before the unlisted feature will throw errors
|
||||||
|
-- when their hash is used to display them, or their url's.
|
||||||
|
-- when proper database migration tools are in place, remove
|
||||||
|
-- this bit of code.
|
||||||
|
if hash == -1 then
|
||||||
|
error("This post was created before the unlisting feature was added. Temporarily, this breaks. You will be able to unlist it in the future.")
|
||||||
|
end
|
||||||
|
loc = loc .. "?pwd=" .. util.encode_unlisted(hash)
|
||||||
|
end
|
||||||
|
--Turning something from not unlisted to unlisted should dirty all these
|
||||||
|
--places anyway, so the post can now be hidden.
|
||||||
|
cache.dirty(string.format("%s/%s",config.domain,id_enc)) -- This place to read this post
|
||||||
|
cache.dirty(string.format("%s",config.domain)) -- The site index (ex, if the author changed the paste from their's to "Anonymous", the cache should reflect that).
|
||||||
|
cache.dirty(string.format("%s.%s",author,config.domain)) -- The author's index, same reasoning as above.
|
||||||
|
cache.dirty(string.format("%s-logout",config.domain))
|
||||||
|
http_response_header(req,"Location",loc)
|
||||||
|
http_response(req,303,"")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
return edit_post
|
|
@ -36,6 +36,7 @@ local endpoint_names = {
|
||||||
archive = {"get"},
|
archive = {"get"},
|
||||||
api = {"get"},
|
api = {"get"},
|
||||||
delete = {"post"},
|
delete = {"post"},
|
||||||
|
bio = {"get","post"},
|
||||||
}
|
}
|
||||||
local endpoints = {}
|
local endpoints = {}
|
||||||
for name, methods in pairs(endpoint_names) do
|
for name, methods in pairs(endpoint_names) do
|
||||||
|
@ -126,7 +127,12 @@ end
|
||||||
|
|
||||||
--TODO
|
--TODO
|
||||||
function edit_bio()
|
function edit_bio()
|
||||||
error("Not yet implemented")
|
local method = http_method_text(req)
|
||||||
|
if method == "GET" then
|
||||||
|
endpoints.bio_edit_get(req)
|
||||||
|
elseif method == "POST" then
|
||||||
|
error("Not yet implemented")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function teardown()
|
function teardown()
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
<% else %>
|
<% else %>
|
||||||
<a href="/_logout" class="button column column-0">Log out</a>
|
<a href="/_logout" class="button column column-0">Log out</a>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
<a href="/_bio" class="button column column-0">Edit bio</a>
|
||||||
<span class="column column-0"></span>
|
<span class="column column-0"></span>
|
||||||
<form action="https://<%= domain %>/_search" method="get" class="search column row">
|
<form action="https://<%= domain %>/_search" method="get" class="search column row">
|
||||||
<input class="column" type="text" name="q" placeholder="+greentext -dotr +hits>20"/>
|
<input class="column" type="text" name="q" placeholder="+greentext -dotr +hits>20"/>
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
<{system cat src/pages/parts/header.etlua}>
|
||||||
|
<h1 class="title">
|
||||||
|
Edit Biography for <%= user %>
|
||||||
|
</h1>
|
||||||
|
<% if err then %><em class="error"><%= err %></em><% end %>
|
||||||
|
<form action="https://<%= user %>.<%= domain %>/_bio" method="post" class="container">
|
||||||
|
<fieldset>
|
||||||
|
<input type="hidden" name="author" value="<%= user %>">
|
||||||
|
<div class="row">
|
||||||
|
<textarea name="text" cols=80 rows=24 class="column"><%= text %></textarea><br/>
|
||||||
|
</div>
|
||||||
|
<input type="submit">
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
<{cat src/pages/parts/footer.etlua}>
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
SELECT biography
|
||||||
|
FROM authors
|
||||||
|
WHERE authors.id = :authorid;
|
|
@ -0,0 +1,3 @@
|
||||||
|
UPDATE authors
|
||||||
|
SET biography = ?
|
||||||
|
WHERE authors.id = ?;
|
Loading…
Reference in New Issue