Add a delete button.
Add a delete button to posts that will show up if the user is logged in and is the owner of a post. If javascript is enabled, the user will be prompted for conformation before deleting a post.
This commit is contained in:
parent
81ad49ae80
commit
069c75b72e
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
There's a delete buttotn to delete a post. If javascript is enabled, replace
|
||||||
|
the button with one that will ask for confirmation before deleting.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function delete_intervine(){
|
||||||
|
var forms = document.getElementsByTagName("form");
|
||||||
|
if(forms.length == 0){return;}//Don't load if the story is missing.
|
||||||
|
var delete_form;
|
||||||
|
for(var i = 0; i < forms.length; i++){
|
||||||
|
if(forms[i].action.endsWith("_delete")){
|
||||||
|
delete_form = forms[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(delete_form == null){return;}//Don't load if we're not logged in
|
||||||
|
var delete_parent = delete_form.parentNode;
|
||||||
|
delete_parent.removeChild(delete_form);
|
||||||
|
var delete_wrapper = document.createElement("div");
|
||||||
|
var delete_button = document.createElement("button");
|
||||||
|
delete_button.classList.add("button");
|
||||||
|
delete_button.classList.add("column");
|
||||||
|
delete_button.classList.add("column-0");
|
||||||
|
delete_button.textContent = "Delete";
|
||||||
|
delete_button.addEventListener("click",function(){
|
||||||
|
if(confirm("Are you sure you want to delete this story?")){
|
||||||
|
document.documentElement.appendChild(delete_form);
|
||||||
|
delete_form.submit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
delete_parent.appendChild(delete_wrapper);
|
||||||
|
delete_wrapper.appendChild(delete_button);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded",delete_intervine,false);
|
|
@ -46,6 +46,7 @@ domain * {
|
||||||
route /_faq asset_serve_faq_html
|
route /_faq asset_serve_faq_html
|
||||||
route /_js/suggest_tags.js asset_serve_suggest_tags_js
|
route /_js/suggest_tags.js asset_serve_suggest_tags_js
|
||||||
route /_js/bookmark.js asset_serve_bookmark_js
|
route /_js/bookmark.js asset_serve_bookmark_js
|
||||||
|
route /_js/intervine_deletion.js asset_serve_intervine_deletion_js
|
||||||
route /favicon.ico asset_serve_favicon_ico
|
route /favicon.ico asset_serve_favicon_ico
|
||||||
route /_paste post_story
|
route /_paste post_story
|
||||||
route /_edit edit_story
|
route /_edit edit_story
|
||||||
|
@ -58,6 +59,7 @@ domain * {
|
||||||
route /_search search
|
route /_search search
|
||||||
route /_archive archive
|
route /_archive archive
|
||||||
route /_api api
|
route /_api api
|
||||||
|
route /_delete delete
|
||||||
# Leading ^ is needed for dynamic routes, kore says the route is dynamic if it does not start with '/'
|
# Leading ^ is needed for dynamic routes, kore says the route is dynamic if it does not start with '/'
|
||||||
route ^/[^_].* read_story
|
route ^/[^_].* read_story
|
||||||
|
|
||||||
|
@ -119,4 +121,7 @@ domain * {
|
||||||
validate call v_any
|
validate call v_any
|
||||||
validate data v_any
|
validate data v_any
|
||||||
}
|
}
|
||||||
|
params post /_delete {
|
||||||
|
validate story v_storyid
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
local tags = require("tags")
|
||||||
|
local util = require("util")
|
||||||
|
local pages = require("pages")
|
||||||
|
local config = require("config")
|
||||||
|
local session = require("session")
|
||||||
|
local db = require("db")
|
||||||
|
local queries = require("queries")
|
||||||
|
local sql = require("lsqlite3")
|
||||||
|
local cache = require("cache")
|
||||||
|
|
||||||
|
local oldconfigure = configure
|
||||||
|
local stmnt_delete
|
||||||
|
function configure(...)
|
||||||
|
stmnt_delete = assert(db.conn:prepare(queries.delete_post),db.conn:errmsg())
|
||||||
|
return oldconfigure(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function delete_post(req)
|
||||||
|
local host = http_request_get_host(req)
|
||||||
|
local path = http_request_get_path(req)
|
||||||
|
http_request_populate_post(req)
|
||||||
|
local storystr = assert(http_argument_get_string(req,"story"))
|
||||||
|
print("Looking at storystr:",storystr)
|
||||||
|
local storyid = util.decode_id(storystr)
|
||||||
|
local author, authorid = session.get(req)
|
||||||
|
if not author then
|
||||||
|
http_response(req, 401, pages.error{
|
||||||
|
errcode = 401,
|
||||||
|
errcodemsg = "Not authorized",
|
||||||
|
explanation = "You must be logged in to delete posts. You are either not logged in or your session has expired.",
|
||||||
|
should_traceback = true
|
||||||
|
})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
log(LOG_DEBUG,string.format("Deleting post %d with proposed owner %d",storyid, authorid))
|
||||||
|
stmnt_delete:bind_names{
|
||||||
|
postid = storyid,
|
||||||
|
authorid = authorid
|
||||||
|
}
|
||||||
|
local err = util.do_sql(stmnt_delete)
|
||||||
|
if err ~= sql.DONE then
|
||||||
|
log(LOG_DEBUG,string.format("Failed to delete: %d:%s",err, db.conn:errmsg()))
|
||||||
|
http_response(req,500,pages.error{
|
||||||
|
errcode = 500,
|
||||||
|
errcodemsg = "Internal error",
|
||||||
|
explanation = "Failed to delete posts from database:" .. db.conn:errmsg(),
|
||||||
|
should_traceback = true,
|
||||||
|
})
|
||||||
|
stmnt_delete:reset()
|
||||||
|
else
|
||||||
|
local loc = string.format("https://%s/%s",config.domain,storystr)
|
||||||
|
http_response_header(req,"Location",loc)
|
||||||
|
http_response(req,303,"")
|
||||||
|
stmnt_delete:reset()
|
||||||
|
cache.dirty(string.format("%s",config.domain))
|
||||||
|
cache.dirty(string.format("%s-logout",config.domain))
|
||||||
|
cache.dirty(string.format("%s.%s",author,config.domain))
|
||||||
|
cache.dirty(string.format("%s",storystr))
|
||||||
|
cache.dirty(string.format("%s?comments=1",storystr))
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return delete_post
|
|
@ -99,7 +99,8 @@ local function read_get(req)
|
||||||
path = http_request_get_path(req),
|
path = http_request_get_path(req),
|
||||||
method = http_method_text(req),
|
method = http_method_text(req),
|
||||||
extra_load = {
|
extra_load = {
|
||||||
'<script src="/_js/bookmark.js"></script>'
|
'<script src="/_js/bookmark.js"></script>',
|
||||||
|
'<script src="/_js/intervine_deletion.js"></script>',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
local err
|
local err
|
||||||
|
|
|
@ -35,6 +35,7 @@ local endpoint_names = {
|
||||||
search = {"get"},
|
search = {"get"},
|
||||||
archive = {"get"},
|
archive = {"get"},
|
||||||
api = {"get"},
|
api = {"get"},
|
||||||
|
delete = {"post"},
|
||||||
}
|
}
|
||||||
local endpoints = {}
|
local endpoints = {}
|
||||||
for name, methods in pairs(endpoint_names) do
|
for name, methods in pairs(endpoint_names) do
|
||||||
|
@ -119,6 +120,10 @@ function edit(req)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function delete(req)
|
||||||
|
endpoints.delete_post(req)
|
||||||
|
end
|
||||||
|
|
||||||
--TODO
|
--TODO
|
||||||
function edit_bio()
|
function edit_bio()
|
||||||
error("Not yet implemented")
|
error("Not yet implemented")
|
||||||
|
|
|
@ -3,10 +3,16 @@
|
||||||
<a href="https://<%= domain %>"><%= domain %></a>/<a href="https://<%= domain %>/<%= idp %>"><%= idp %></a>
|
<a href="https://<%= domain %>"><%= domain %></a>/<a href="https://<%= domain %>/<%= idp %>"><%= idp %></a>
|
||||||
</nav>
|
</nav>
|
||||||
<% if owner then -%>
|
<% if owner then -%>
|
||||||
|
<div class="row">
|
||||||
<form action="https://<%= domain %>/_edit" method="get"><fieldset>
|
<form action="https://<%= domain %>/_edit" method="get"><fieldset>
|
||||||
<input type="hidden" name="story" value="<%= idp %>"/>
|
<input type="hidden" name="story" value="<%= idp %>"/>
|
||||||
<input type="submit" value="edit" class="button"/>
|
<input type="submit" value="edit" class="button column column-0"/>
|
||||||
</fieldset></form>
|
</fieldset></form>
|
||||||
|
<form action="https://<%= domain %>/_delete" method="post"><fieldset>
|
||||||
|
<input type="hidden" name="story" value="<%= idp %>"/>
|
||||||
|
<input type="submit" value="delete" class="button column column-0"/>
|
||||||
|
</fieldset></form>
|
||||||
|
</div>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
<article>
|
<article>
|
||||||
<h2 class="title"> <%- title %> </h2>
|
<h2 class="title"> <%- title %> </h2>
|
||||||
|
|
36
src/smr.c
36
src/smr.c
|
@ -29,6 +29,7 @@ int archive(struct http_request *);
|
||||||
int api(struct http_request *);
|
int api(struct http_request *);
|
||||||
int style(struct http_request *);
|
int style(struct http_request *);
|
||||||
int miligram(struct http_request *);
|
int miligram(struct http_request *);
|
||||||
|
int delete(struct http_request *);
|
||||||
int do_lua(struct http_request *req, const char *name);
|
int do_lua(struct http_request *req, const char *name);
|
||||||
int errhandeler(lua_State *);
|
int errhandeler(lua_State *);
|
||||||
lua_State *L;
|
lua_State *L;
|
||||||
|
@ -56,26 +57,26 @@ KORE_SECCOMP_FILTER("app",
|
||||||
);
|
);
|
||||||
|
|
||||||
int
|
int
|
||||||
errhandeler(lua_State *L){
|
errhandeler(lua_State *state){
|
||||||
printf("Error: %s\n",lua_tostring(L,1));//"error"
|
printf("Error: %s\n",lua_tostring(state,1));//"error"
|
||||||
lua_getglobal(L,"debug");//"error",{debug}
|
lua_getglobal(state,"debug");//"error",{debug}
|
||||||
lua_getglobal(L,"print");//"error",{debug},print()
|
lua_getglobal(state,"print");//"error",{debug},print()
|
||||||
lua_getfield(L,-2,"traceback");//"error",{debug},print(),traceback()
|
lua_getfield(state,-2,"traceback");//"error",{debug},print(),traceback()
|
||||||
lua_call(L,0,1);//"error",{debug},print(),"traceback"
|
lua_call(state,0,1);//"error",{debug},print(),"traceback"
|
||||||
lua_call(L,1,0);//"error",{debug}
|
lua_call(state,1,0);//"error",{debug}
|
||||||
printf("Called print()\n");
|
printf("Called print()\n");
|
||||||
lua_getfield(L,-1,"traceback");//"error",{debug},traceback()
|
lua_getfield(state,-1,"traceback");//"error",{debug},traceback()
|
||||||
printf("got traceback\n");
|
printf("got traceback\n");
|
||||||
lua_call(L,0,1);//"error",{debug},"traceback"
|
lua_call(state,0,1);//"error",{debug},"traceback"
|
||||||
lua_pushstring(L,"\n");
|
lua_pushstring(state,"\n");
|
||||||
printf("called traceback\n");
|
printf("called traceback\n");
|
||||||
lua_pushvalue(L,-4);//"error",{debug},"traceback","error"
|
lua_pushvalue(state,-4);//"error",{debug},"traceback","error"
|
||||||
printf("pushed error\n");
|
printf("pushed error\n");
|
||||||
lua_concat(L,3);//"error",{debug},"traceback .. error"
|
lua_concat(state,3);//"error",{debug},"traceback .. error"
|
||||||
printf("concated\n");
|
printf("concated\n");
|
||||||
int ref = luaL_ref(L,LUA_REGISTRYINDEX);//"error",{debug}
|
int ref = luaL_ref(state,LUA_REGISTRYINDEX);//"error",{debug}
|
||||||
lua_pop(L,2);//
|
lua_pop(state,2);//
|
||||||
lua_rawgeti(L,LUA_REGISTRYINDEX,ref);//"traceback .. error"
|
lua_rawgeti(state,LUA_REGISTRYINDEX,ref);//"traceback .. error"
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,6 +180,11 @@ home(struct http_request *req){
|
||||||
return do_lua(req,"home");
|
return do_lua(req,"home");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
delete(struct http_request *req){
|
||||||
|
return do_lua(req,"delete");
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
kore_worker_configure(void){
|
kore_worker_configure(void){
|
||||||
printf("Configuring worker...\n");
|
printf("Configuring worker...\n");
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
DELETE FROM posts
|
||||||
|
WHERE posts.id = :postid AND
|
||||||
|
posts.authorid = :authorid
|
Loading…
Reference in New Issue