diff --git a/core.lua b/core.lua index d6aa00e..e4ec723 100644 --- a/core.lua +++ b/core.lua @@ -65,6 +65,31 @@ local handler = function(req, res) res:statusCode(403) end res:write"" + elseif req:path():match"^/addtags/?$" then + if verified and verified.privs >= DB.USER_PRIVS_APPROVED then + local pohst = req:post() + + local returndata = {} + + if pohst.csrf and DB.csrfverify(verified.id, Escapes.urlunescape(pohst.csrf)) then + local names = pohst["name[]"] + local tcs = pohst["tc[]"] + local adults = pohst["adult[]"] + + if #names == #tcs and #names == #adults then + for tag = 1, #names do + local tagid = DB.tagadd(tostring(names[tag]), (tonumber(tcs[tag]) or 0) + 1, tostring(adults[tag]) == "1") + table.insert(returndata, tagid) + end + end + end + + res:statusCode(200) + res:write(table.concat(returndata, ",")) + else + res:statusCode(403) + res:write"" + end elseif req:path():match"^/verif/?$" then res:addHeader("Set-Cookie", "sesh=" .. (req.querystring.q or "") .. "; SameSite=Lax; Secure; HttpOnly") res:addHeader("Location", "/") @@ -183,4 +208,4 @@ local handler = function(req, res) end end -return handler \ No newline at end of file +return handler diff --git a/db.lua b/db.lua index 03183cd..0d6b925 100644 --- a/db.lua +++ b/db.lua @@ -416,7 +416,11 @@ local function tagadd(name, category, adultonly) pingdb() - return not not SQLConn:execute("INSERT INTO tags (name, category, adultonly) VALUES ('" .. SQLConn:escape(name) .. "', " .. category .. ", " .. (adultonly and 1 or 0) .. ");") + local cur = SQLConn:execute("INSERT INTO tags (name, category, adultonly) VALUES ('" .. SQLConn:escape(name) .. "', " .. category .. ", " .. (adultonly and 1 or 0) .. ");") + + if not cur then return nil end + + return tonumber(SQLConn:getlastautoid()) end local function regnewobj(ownerid, approved, published) diff --git a/index.html.l b/index.html.l index 1766d46..ae94661 100644 --- a/index.html.l +++ b/index.html.l @@ -1,7 +1,7 @@ {% title = BigGlobe.cfg.sitename .. " - generic object database inspired by imageboards" %} {% function content() %} -
+

{{ Escapes.htmlescape(BigGlobe.cfg.sitename) }}

@@ -81,4 +81,4 @@ {% end %} -{# base.inc \ No newline at end of file +{# base.inc diff --git a/obj.html.l b/obj.html.l index e0c088c..9511a4c 100644 --- a/obj.html.l +++ b/obj.html.l @@ -4,6 +4,8 @@ obj = DB.getobj(DB.objshowid(request:path():sub(7, 7 + 31))) end + local filecount = 0 + if obj then local virt = "/objd/" .. DB.objhideid(obj.id) .. "/" local phys = DB.urltophysical(virt) @@ -13,6 +15,10 @@ if f ~= "." and f ~= ".." then local attribs = LFS.attributes(phys .. f) table.insert(files, {name = f, size = attribs.size, modtime = attribs.modification, phys = phys .. f, virt = virt .. f}) + + if f ~= ".thumb.jpg" then + filecount = filecount + 1 + end end end @@ -41,7 +47,7 @@

{{ Escapes.htmlescape(obj.name) }}{% if verified and verified.id == obj.owner then %} (edit){% end %}

{{ Escapes.htmlescape(owner.displayname) }} {{ obj.createtime }}
-

Object has {{#files-1}} files:

+

Object has {{filecount}} files:

    {% for _,f in pairs(files) do %} {% if f.name ~= ".thumb.jpg" then %}
  • {{ Escapes.htmlescape(f.name) }} ({{ (f.size + 1023) // 1024 }}kB)
  • {% end %} @@ -159,4 +165,4 @@ {% end %} {% end %} -{# base.inc \ No newline at end of file +{# base.inc diff --git a/obje.html.l b/obje.html.l index 8d23781..6ddc563 100644 --- a/obje.html.l +++ b/obje.html.l @@ -147,7 +147,7 @@

Tags

-
+
0 then %} style="visibility:hidden;"{% end %}>Enter tags...

{% for _, tag in pairs(tags) do %}
{{ Escapes.htmlescape(tag.name) }}
@@ -175,15 +175,28 @@
+ + @@ -348,4 +440,4 @@ {% end %} {% end %} -{# base.inc \ No newline at end of file +{# base.inc diff --git a/pegasus/request.lua b/pegasus/request.lua index aba78db..ff81637 100644 --- a/pegasus/request.lua +++ b/pegasus/request.lua @@ -153,7 +153,15 @@ function Request:parseMultipartFormData(data) } end else - output[name] = itemdata + if name:sub(#name - 1) == "[]" then + if output[name] then + table.insert(output[name], itemdata) + else + output[name] = {itemdata} + end + else + output[name] = itemdata + end end end end diff --git a/static/style.css b/static/style.css index 44d3196..0845255 100644 --- a/static/style.css +++ b/static/style.css @@ -11,6 +11,7 @@ div.tagbox { user-select: contain; padding: 0.4em; border-radius: 3px; + box-sizing: border-box; } div.tagbox::after { content: "penis"; @@ -113,6 +114,7 @@ input[type='text'], input[type='number'] { border: 1px solid gray; border-radius: 3px; font-size: 1em; + box-sizing: border-box; } input::placeholder { color: #C0C0C0; @@ -125,6 +127,7 @@ ul.over18 { padding: 0 0.4em 0 0.4em; width: 100%; text-align: center; + box-sizing: border-box; } ul.over18 label { cursor: pointer; @@ -210,4 +213,27 @@ footer { margin-top: 2em; width: 100%; text-align: center; -} \ No newline at end of file +} + +div.tag.tcNew::before { + content: "New"; +} + +div#newtagsform { + position: fixed; + width: 50vw; + height: 50vh; + top: 25vh; + left: 25vw; + background: white; + border: 1px solid black; + padding: 1em; +} + +div#newtagsform select { + border: 0; +} + +.hidden { + visibility: hidden; +} diff --git a/static/tagbox.js b/static/tagbox.js index ec9e4c7..5b6db09 100644 --- a/static/tagbox.js +++ b/static/tagbox.js @@ -1,13 +1,28 @@ +function createtag(name, tc, tagid) { + var newtag = document.createElement("div") + newtag.classList.toggle("tag") + newtag.classList.toggle("tc" + (tc || "New")) + if(tagid) { + newtag.setAttribute("data-tagid", tagid) + } + newtag.innerText = name + return newtag +} + var acTimer; -document.getElementById(document.querySelector("div.tagbox").getAttribute("data-formid")).addEventListener("submit", function(ev) { +function tagbox_updateformdata() { document.getElementById(document.querySelector("div.tagbox").getAttribute("data-formparaminputid")).value = Array.from(document.querySelectorAll("div.tagbox div.tag")).map(function(a) {return a.getAttribute("data-tagid")}).join(",") -}) +} + +document.getElementById(document.querySelector("div.tagbox").getAttribute("data-formid")).addEventListener("submit", tagbox_updateformdata) document.querySelector("div.tagbox").onclick = function(ev) { this.querySelector('span').focus() } +var UnknownTagsMode = document.querySelector("div.tagbox").getAttribute("data-unknowntags") !== null + document.querySelector("div.tagbox span").onkeydown = function(ev) { if(ev.keyCode == 13) { ev.preventDefault() @@ -15,16 +30,18 @@ document.querySelector("div.tagbox span").onkeydown = function(ev) { if(document.querySelector("div.tagbox span").innerText.length) { var from = document.querySelector("div.autocomplete > div.tag.selected") || document.querySelectorAll("div.autocomplete > div.tag")[0] - if(!document.querySelector("div.tagbox div.tag[data-tagid='"+from.getAttribute("data-tagid")+"']")) { - from.classList.remove("selected") - - document.querySelector("div.tagbox span").innerText = "" - document.querySelector("div.tagbox").insertBefore(from, document.querySelector("div.tagbox span")) - document.querySelector("div.tagbox").insertBefore(document.createTextNode("\n"), document.querySelector("div.tagbox span")) - - var ac = document.querySelector(".autocomplete") - ac.style.visibility = "hidden" + if(from) { + if(!document.querySelector("div.tagbox div.tag[data-tagid='"+from.getAttribute("data-tagid")+"']")) { + from.classList.remove("selected") + + document.querySelector("div.tagbox").insertBefore(from, document.querySelector("div.tagbox span")) + document.querySelector("div.tagbox").insertBefore(document.createTextNode("\n"), document.querySelector("div.tagbox span")) + } } + + document.querySelector("div.tagbox span").innerText = "" + var ac = document.querySelector(".autocomplete") + ac.style.visibility = "hidden" } else { document.getElementById(document.querySelector("div.tagbox").getAttribute("data-formid")).querySelector("input[type='submit']").click() } @@ -75,16 +92,17 @@ document.querySelector("div.tagbox span").oninput = function(ev) { var ac = document.querySelector(".autocomplete") ac.style.visibility = "" while(ac.firstChild) ac.removeChild(ac.firstChild) - if(ajax.responseText == "") { + if(!UnknownTagsMode && ajax.responseText == "") { ac.innerText = "No such tags found" - } else ajax.responseText.split("\n").slice(0, -1).forEach(function(line) { - var newtag = document.createElement("div") - newtag.classList.toggle("tag") - newtag.classList.toggle("tc" + line.split(",")[2]) - newtag.setAttribute("data-tagid", line.split(",")[0]) - newtag.innerText = line.split(",")[1] - ac.insertBefore(newtag, null) - }) + } else { + ajax.responseText.split("\n").slice(0, -1).forEach(function(line) { + ac.insertBefore(createtag(line.split(",")[1], line.split(",")[2], line.split(",")[0]), null) + }) + + if(UnknownTagsMode) { + ac.insertBefore(createtag(document.querySelector("div.tagbox span").innerText, null, null), null); + } + } } } ajax.send() @@ -97,4 +115,4 @@ document.querySelector("div.tagbox span").oninput = function(ev) { clearTimeout(acTimer) acTimer = undefined } -} \ No newline at end of file +}