From d5ec6d6864c3e10185f98d4c921124c68b97d079 Mon Sep 17 00:00:00 2001 From: Robin Malley Date: Fri, 2 Sep 2022 23:24:39 +0000 Subject: [PATCH] Get started on author biography. Get started on implementing author biographies, add endpoints. --- spec/typeing.lua | 5 ++ spec/utils.lua | 8 +++ src/lua/endpoints/bio_get.lua | 69 ++++++++++++++++++++ src/lua/endpoints/bio_post.lua | 108 ++++++++++++++++++++++++++++++++ src/lua/init.lua | 8 ++- src/pages/author_index.etlua.in | 1 + src/pages/edit_bio.etlua.in | 16 +++++ src/sql/select_author_bio.sql | 3 + src/sql/update_bio.sql | 3 + 9 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 spec/utils.lua create mode 100644 src/lua/endpoints/bio_get.lua create mode 100644 src/lua/endpoints/bio_post.lua create mode 100644 src/pages/edit_bio.etlua.in create mode 100644 src/sql/select_author_bio.sql create mode 100644 src/sql/update_bio.sql diff --git a/spec/typeing.lua b/spec/typeing.lua index 4d37187..d94510a 100644 --- a/spec/typeing.lua +++ b/spec/typeing.lua @@ -16,6 +16,11 @@ describe("smr type checking",function() types.number(t) 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) diff --git a/spec/utils.lua b/spec/utils.lua new file mode 100644 index 0000000..9987323 --- /dev/null +++ b/spec/utils.lua @@ -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 diff --git a/src/lua/endpoints/bio_get.lua b/src/lua/endpoints/bio_get.lua new file mode 100644 index 0000000..16bc9dc --- /dev/null +++ b/src/lua/endpoints/bio_get.lua @@ -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 diff --git a/src/lua/endpoints/bio_post.lua b/src/lua/endpoints/bio_post.lua new file mode 100644 index 0000000..3a75a30 --- /dev/null +++ b/src/lua/endpoints/bio_post.lua @@ -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 diff --git a/src/lua/init.lua b/src/lua/init.lua index d671694..1cc5abe 100644 --- a/src/lua/init.lua +++ b/src/lua/init.lua @@ -36,6 +36,7 @@ local endpoint_names = { archive = {"get"}, api = {"get"}, delete = {"post"}, + bio = {"get","post"}, } local endpoints = {} for name, methods in pairs(endpoint_names) do @@ -126,7 +127,12 @@ end --TODO 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 function teardown() diff --git a/src/pages/author_index.etlua.in b/src/pages/author_index.etlua.in index 927402f..d5f4412 100644 --- a/src/pages/author_index.etlua.in +++ b/src/pages/author_index.etlua.in @@ -12,6 +12,7 @@ <% else %> Log out <% end %> + Edit bio +<{cat src/pages/parts/footer.etlua}> + diff --git a/src/sql/select_author_bio.sql b/src/sql/select_author_bio.sql new file mode 100644 index 0000000..f9800f3 --- /dev/null +++ b/src/sql/select_author_bio.sql @@ -0,0 +1,3 @@ +SELECT biography +FROM authors +WHERE authors.id = :authorid; diff --git a/src/sql/update_bio.sql b/src/sql/update_bio.sql new file mode 100644 index 0000000..b24a724 --- /dev/null +++ b/src/sql/update_bio.sql @@ -0,0 +1,3 @@ +UPDATE authors +SET biography = ? +WHERE authors.id = ?;