Initial commit
This commit is contained in:
351
obje.html.l
Normal file
351
obje.html.l
Normal file
@@ -0,0 +1,351 @@
|
||||
{%
|
||||
local obj, files, usedSpace, tags, tagcount
|
||||
if DB.isobjhexvalid(request:path():sub(7, 7 + 31)) then
|
||||
obj = DB.getobj(DB.objshowid(request:path():sub(7, 7 + 31)))
|
||||
end
|
||||
|
||||
function recalcfiles()
|
||||
local virt = "/objd/" .. DB.objhideid(obj.id) .. "/"
|
||||
local phys = DB.urltophysical(virt)
|
||||
|
||||
files = {}
|
||||
usedSpace = 0
|
||||
for f in LFS.dir(phys) do
|
||||
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})
|
||||
usedSpace = usedSpace + attribs.size
|
||||
end
|
||||
end
|
||||
table.sort(files, function(a,b)
|
||||
if a.modtime == b.modtime then
|
||||
return a.name < b.name
|
||||
else
|
||||
return a.modtime < b.modtime
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
if obj then
|
||||
-- !!!CHECK IF OWNER HAPPENS HERE!!!
|
||||
if verified and (verified.id ~= obj.owner) then
|
||||
verified = nil
|
||||
end
|
||||
|
||||
recalcfiles()
|
||||
|
||||
tags, tagcount = DB.getobjtags(obj.id)
|
||||
|
||||
if verified then
|
||||
obj.sizequota = BigGlobe.cfg.maxtotalobjsize * 1024 -- Temporary
|
||||
|
||||
local post = request:post()
|
||||
if post and post.csrf and DB.csrfverify(verified.id, Escapes.urlunescape(tostring(post.csrf))) then
|
||||
if post["createfiles"] then
|
||||
local sztoadd = 0
|
||||
for fn, sz in post["createfiles"]:gmatch"([^;]+);(%d+)" do
|
||||
sztoadd = sztoadd + sz
|
||||
end
|
||||
if usedSpace + sztoadd > obj.sizequota then
|
||||
response:statusCode(409)
|
||||
else
|
||||
for fn, sz in post["createfiles"]:gmatch"([^;]+);(%d+)" do
|
||||
DB.createfile(obj.id, Escapes.urlunescape(fn), tonumber(sz))
|
||||
end
|
||||
end
|
||||
return
|
||||
elseif post["upchu"] then
|
||||
DB.updatefile(obj.id, post["upchu"], tonumber(post["offset"]), post["data"].data)
|
||||
return
|
||||
elseif post["remfiles"] then
|
||||
for d in post["remfiles"]:gmatch"(%d+)" do
|
||||
DB.remfilefromobj(obj.id, files[tonumber(d) + 1].name)
|
||||
end
|
||||
return
|
||||
else
|
||||
recalcfiles()
|
||||
|
||||
if tonumber(post.newthumbnail) and files[tonumber(post.newthumbnail)] then
|
||||
DB.genobjthumbnail(obj.id, files[tonumber(post.newthumbnail)].name, obj.sizequota - usedSpace)
|
||||
recalcfiles()
|
||||
end
|
||||
|
||||
if post["objname"] then
|
||||
local newname = Escapes.urlunescape(post["objname"])
|
||||
local newpublished = usedSpace > 0
|
||||
if newname ~= obj.name or obj.published ~= newpublished then
|
||||
if DB.objupdate(obj.id, newname, newpublished) then
|
||||
obj.name = newname
|
||||
obj.published = newpublished
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if post["objtags"] then
|
||||
local newtagset = {}
|
||||
for m in post["objtags"]:gmatch"%d+" do
|
||||
newtagset[tonumber(m)] = true
|
||||
end
|
||||
|
||||
local tagstoremove = {}
|
||||
for k,_ in pairs(tags) do
|
||||
if not newtagset[k] then
|
||||
table.insert(tagstoremove, k)
|
||||
end
|
||||
end
|
||||
|
||||
local tagstoadd = {}
|
||||
for k,_ in pairs(newtagset) do
|
||||
if not tags[k] then
|
||||
table.insert(tagstoadd, k)
|
||||
end
|
||||
end
|
||||
|
||||
DB.remtagsfromobj(obj.id, tagstoremove)
|
||||
DB.addtagstoobj(obj.id, tagstoadd)
|
||||
|
||||
tags, tagcount = DB.getobjtags(obj.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
title = BigGlobe.cfg.sitename .. " - Editing " .. (obj and obj.name or "Object not found")
|
||||
|
||||
function content() %}
|
||||
{% if obj then %}
|
||||
{% if verified then %}
|
||||
<form method="post" enctype="multipart/form-data" action="#" id="editform">
|
||||
<div style="display:inline-block;vertical-align:top;width:49%;">
|
||||
<h2>Editing object</h2>
|
||||
<input type="hidden" name="csrf" value="{{ Escapes.htmlescape(DB.csrf(verified.id)) }}" />
|
||||
|
||||
<div><label>Name: </label><input type="text" name="objname" autocomplete="off" value="{{ Escapes.htmlescape(obj.name) }}" /></div>
|
||||
|
||||
<div><p>Once files are uploaded, the object will be considered published.</p></div>
|
||||
|
||||
<div><p>Object sized at <strong>{{ (usedSpace + 1023) // 1024 }}kB</strong> out of <strong>{{ (obj.sizequota + 1023) // 1024 }}kB</strong> maximum (<strong>{{math.floor(usedSpace / obj.sizequota * 1000 + 0.5) / 10}}%</strong>) </p></div>
|
||||
|
||||
<table style="margin-top:1em"><thead><tr><td>File</td><td>Size</td><td colspan="3">Actions</td></tr></thead><tbody>
|
||||
{% for idx,f in pairs(files) do %}
|
||||
<tr>
|
||||
<td>{{ Escapes.htmlescape(f.name) }}</td>
|
||||
<td>{{ (f.size + 1023) // 1024 }}kB</td>
|
||||
<td><input type="checkbox" id="delcb{{ idx }}"><label for="delcb{{ idx }}">Delete</label></td>
|
||||
</tr>
|
||||
{% end %}
|
||||
<tr style="{% if #files >= BigGlobe.cfg.maxfilesperobj then %}display:none;{% end %}"><td><input type="file" /><button type="button" style="margin:0;" onclick="clearfile(this)">Clear</button></td><td></td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<select name="newthumbnail" style="margin-top: 1em; margin-bottom: 1em; display: block;">
|
||||
<option value="none" selected>Generate thumbnail from image file...</option>
|
||||
{% for idx,f in pairs(files) do %}
|
||||
<option value="{{idx}}">{{ Escapes.htmlescape(f.name) }}</option>
|
||||
{% end %}
|
||||
</select>
|
||||
</div>
|
||||
<div style="display:inline-block;vertical-align:top;width:49%;">
|
||||
<h2>Tags</h2>
|
||||
<div style="position:relative;width:80%;" class="tagbox" data-formid="editform" data-formparaminputid="objtagsparam">
|
||||
<p{% if tagcount > 0 then %} style="visibility:hidden;"{% end %}>Enter tags...</p>
|
||||
{% for _, tag in pairs(tags) do %}
|
||||
<div class="tag tc{{ tag.category }}" data-tagid="{{ tag.id }}">{{ Escapes.htmlescape(tag.name) }}</div>
|
||||
{% end %}
|
||||
<span style="position:relative;min-width:4px;left:0;" contenteditable></span>
|
||||
</div>
|
||||
<div class="autocomplete" style="visibility:hidden;width:80%;"></div>
|
||||
<input type="hidden" id="objtagsparam" name="objtags" value="" />
|
||||
|
||||
{% if BigGlobe.cfg.enable18plus then %}
|
||||
<ul class="over18" style="width: 80%;">
|
||||
<li>
|
||||
<input type="radio" name="a" value="-1" id="o18h" onchange="upd(false)" />
|
||||
<label for="o18h">Hide 18+</label>
|
||||
</li><li>
|
||||
<input type="radio" name="a" value="0" id="o18s" onchange="upd(true)" />
|
||||
<label for="o18s">Show 18+</label>
|
||||
</li>
|
||||
</ul>
|
||||
{% end %}
|
||||
</div>
|
||||
<div style="text-align:center;">
|
||||
<input type="submit" value="Submit" />
|
||||
<progress id="proggers" max="1" value="0" />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
{% if BigGlobe.cfg.enable18plus then %}
|
||||
function upd(over18) {
|
||||
document.querySelector(".tagbox").setAttribute("data-over18", +over18 != -1)
|
||||
}
|
||||
var activeo18 = "-1"
|
||||
if(window.localStorage.getItem("o18")) {
|
||||
activeo18 = window.localStorage.getItem("o18")
|
||||
}
|
||||
upd(activeo18)
|
||||
document.querySelector("ul.over18 input[type=\"radio\"][value=\"" + activeo18 + "\"]").checked = true
|
||||
{% end %}
|
||||
|
||||
var totalfiles = {{ #files }}
|
||||
|
||||
function clearfile(el) {
|
||||
var inp = el.parentElement.querySelector("input")
|
||||
inp.value = ""
|
||||
|
||||
var allofem = Array.from(document.querySelectorAll("input[type='file']"))
|
||||
|
||||
var idx = allofem.indexOf(inp)
|
||||
if(idx != allofem.length - 1) {
|
||||
// remove row
|
||||
el.parentElement.parentElement.parentElement.removeChild(el.parentElement.parentElement)
|
||||
|
||||
if(totalfiles == {{ BigGlobe.cfg.maxfilesperobj }}) {
|
||||
allofem[allofem.length - 1].parentElement.parentElement.style.display = ""
|
||||
}
|
||||
|
||||
totalfiles--
|
||||
}
|
||||
}
|
||||
|
||||
function rebind() {
|
||||
var v = document.querySelectorAll("input[type='file']")
|
||||
var last = v[v.length - 1]
|
||||
last.onchange = function(ev) {
|
||||
last.onchange = undefined
|
||||
|
||||
var tablerow = this.parentElement.parentElement
|
||||
var clond = tablerow.cloneNode(true)
|
||||
tablerow.parentElement.appendChild(clond)
|
||||
clond.querySelector("input").value = ""
|
||||
|
||||
totalfiles++
|
||||
|
||||
if(totalfiles == {{ BigGlobe.cfg.maxfilesperobj }}) {
|
||||
clond.style.display = "none"
|
||||
}
|
||||
|
||||
rebind()
|
||||
}
|
||||
}
|
||||
|
||||
rebind()
|
||||
|
||||
var CHUNK_SIZE = 1024 * 512
|
||||
|
||||
var files
|
||||
|
||||
var totalsizetoupload
|
||||
var totaluploaded
|
||||
|
||||
function send(fileidx, offset) {
|
||||
var xhr = new XMLHttpRequest()
|
||||
xhr.open("POST", "#", true)
|
||||
|
||||
var sz = Math.min(CHUNK_SIZE, files[fileidx].files[0].size - offset)
|
||||
|
||||
var formData = new FormData()
|
||||
formData.append("csrf", document.querySelector("[name='csrf']").value)
|
||||
formData.append("upchu", encodeURIComponent(files[fileidx].files[0].name))
|
||||
formData.append("offset", offset)
|
||||
formData.append("data", files[fileidx].files[0].slice(offset, offset + sz))
|
||||
xhr.onreadystatechange = function() {
|
||||
if(xhr.readyState == XMLHttpRequest.DONE) {
|
||||
if(xhr.status == 200) {
|
||||
document.getElementById("proggers").value = totaluploaded / totalsizetoupload
|
||||
totaluploaded += sz
|
||||
|
||||
if(sz < CHUNK_SIZE) {
|
||||
if(fileidx < files.length - 1) {
|
||||
send(fileidx + 1, 0)
|
||||
} else {
|
||||
var daform = document.getElementById("editform")
|
||||
for(var i = 0; i < files.length; i++) files[i].disabled = true
|
||||
daform.submit()
|
||||
}
|
||||
} else {
|
||||
send(fileidx, offset + sz)
|
||||
}
|
||||
} else {
|
||||
send(fileidx, offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
xhr.send(formData)
|
||||
}
|
||||
|
||||
function testsizes() {
|
||||
var xhr = new XMLHttpRequest()
|
||||
xhr.open("POST", "#", true)
|
||||
|
||||
var formData = new FormData()
|
||||
formData.append("csrf", document.querySelector("[name='csrf']").value)
|
||||
formData.append("createfiles", files.map(function(x) {return [encodeURIComponent(x.files[0].name), x.files[0].size]}).flat().join(";"))
|
||||
|
||||
totalsizetoupload = files.map(function(x) {return x.files[0].size}).reduce(function(x,y){return x+y}, 0)
|
||||
totaluploaded = 0
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if(xhr.readyState == XMLHttpRequest.DONE) {
|
||||
if(xhr.status == 200) {
|
||||
send(0, 0)
|
||||
} else {
|
||||
alert("Too much space.")
|
||||
window.location.href = window.location.href.split("#")[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
xhr.send(formData)
|
||||
}
|
||||
|
||||
function doremoves() {
|
||||
var xhr = new XMLHttpRequest()
|
||||
xhr.open("POST", "#", true)
|
||||
|
||||
var idxs = []
|
||||
|
||||
var remchecks = document.querySelectorAll("#editform input[type='checkbox']")
|
||||
for(var i = 0; i < remchecks.length; i++) {
|
||||
if(remchecks[i].checked) idxs.push(i)
|
||||
}
|
||||
|
||||
var formData = new FormData()
|
||||
formData.append("csrf", document.querySelector("[name='csrf']").value)
|
||||
formData.append("remfiles", idxs.join(";"))
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if(xhr.readyState == XMLHttpRequest.DONE) {
|
||||
if(xhr.status == 200) {
|
||||
if(files.length > 0) {
|
||||
testsizes()
|
||||
} else {
|
||||
document.getElementById("editform").submit()
|
||||
}
|
||||
} else {
|
||||
window.location.href = window.location.href.split("#")[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
xhr.send(formData)
|
||||
}
|
||||
|
||||
document.getElementById("editform").addEventListener("submit", function(ev) {
|
||||
ev.preventDefault()
|
||||
|
||||
files = Array.from(document.querySelectorAll("input[type='file']"))
|
||||
files.pop() // don't count empty input
|
||||
|
||||
doremoves()
|
||||
})
|
||||
</script>
|
||||
<script src="/static/tagbox.js"></script>
|
||||
{% else %}
|
||||
<p>You are not eligible to edit this object.</p>
|
||||
{% end %}
|
||||
{% else %}
|
||||
<p>Object was not found.</p>
|
||||
{% end %}
|
||||
{% end %}
|
||||
|
||||
{# base.inc
|
||||
Reference in New Issue
Block a user