-- vim: ft=terra
local pstr = lib.str.t
local terra cs(s: rawstring)
return pstr { ptr = s, ct = lib.str.sz(s) }
end
local show_all,show_new,show_unfiled,show_files,show_vid,show_img=1,2,3,4,5,6
local terra
render_media_gallery(co: &lib.srv.convo, path: lib.mem.ptr(lib.mem.ref(int8)), uid: uint64, acc: &lib.str.acc)
-- note that when calling this function, path must be adjusted so that path(0)
-- eq "media"
var owner = false
if co.aid ~= 0 and co.who.id == uid then owner = true end
var ou = co.srv:actor_fetch_uid(uid)
if not ou then goto e404 end
do defer ou:free()
var pfx = pstr.null()
if not owner then
var pa = co:stra(32)
pa:lpush('/')
if ou(0).origin ~= 0 then pa:lpush('@') end
pa:push(ou(0).xid,0)
pfx = pa:finalize()
end
if path.ct >= 3 and path(1):cmp('a') then
var id, idok = lib.math.shorthand.parse(path(2).ptr, path(2).ct)
if not idok then goto e404 end
var art = co.srv:artifact_fetch(uid, id)
if not art then goto e404 end
if path.ct == 3 then
-- sniff out the artifact type and display the appropriate viewer
var artid = cs(art(0).url)
var btns: lib.str.acc
if owner then
btns:pcompose(&co.srv.pool,'<a class="neg button" href="',pfx,'/media/a/',artid,'/del">delete</a><a class="button" href="',pfx,'/media/a/',artid,'/edit">alter</a>')
else
btns:pcompose(&co.srv.pool,'<a class="pos button" href="',pfx,'/media/a/',artid,'/collect">collect</a>')
end
var btntxt = btns:finalize() -- defer btntxt:free()
var desc = lib.smackdown.html(&co.srv.pool, pstr{art(0).desc,0}, true) -- defer desc:free()
var viewerprops = {
pfx = pfx, desc = desc;
id = artid; btns = btntxt;
}
if lib.str.ncmp(art(0).mime, 'image/', 6) == 0 then
var view = data.view.media_image(viewerprops)
var pg = view:poolstr(&co.srv.pool)
co:stdpage([lib.srv.convo.page] {
title = 'media :: image';
class = 'media viewer img';
cache = false, body = pg;
})
--pg:free()
elseif lib.str.cmp(art(0).mime, 'text/markdown') == 0 then
var view = data.view.media_text(viewerprops)
var text, mime = co.srv:artifact_load(id) mime:free()
view.text = lib.smackdown.html(&co.srv.pool, pstr{[rawstring](text.ptr),text.ct}, false)
text:free()
var pg = view:poolstr(&co.srv.pool)
--view.text:free()
co:stdpage([lib.srv.convo.page] {
title = 'media :: text';
class = 'media viewer text';
cache = false, body = pg;
})
--pg:free()
elseif
lib.str.ncmp(art(0).mime, 'text/', 5) == 0 or
lib.str.cmp(art(0).mime, 'application/x-perl') == 0 or
lib.str.cmp(art(0).mime, 'application/sql') == 0
-- and so on (we need a mimelib at some point) --
then
var view = data.view.media_text(viewerprops)
var text, mime = co.srv:artifact_load(id) mime:free()
var san = lib.html.sanitize(&co.srv.pool,pstr{[rawstring](text.ptr),text.ct}, false)
text:free()
view.text = co:qstr('<pre>',san,'</pre>')
--san:free()
var pg = view:poolstr(&co.srv.pool)
--view.text:free()
co:stdpage([lib.srv.convo.page] {
title = 'media :: text';
class = 'media viewer text';
cache = false, body = pg;
})
--pg:free()
else co:complain(500,'bad file type','this file type is not supported') end
elseif path.ct == 4 then
var act = path(3)
var curl = co:qstr('/media/a/', path(2))
-- defer curl:free()
if act:cmp('avi') and lib.str.ncmp(art(0).mime, 'image/', 6) == 0 then
co:confirm('set avatar', 'are you sure you want this image to be your new avatar?',curl)
elseif act:cmp('del') then
co:confirm('delete', 'are you sure you want to permanently delete this artifact?',curl)
else goto e404 end
end
else
var mode: uint8 = show_new
var folder: pstr
if path.ct == 2 then
if path(1):cmp('unfiled') then
mode=show_unfiled
elseif path(1):cmp('all') then
mode=show_all
else goto e404 end
elseif path.ct == 3 and path(1):cmp('kind') then
end
var folders = co.srv:artifact_folder_enum(uid)
if mode == show_new then
folder = ''
elseif mode == show_all or mode == show_unfiled then
folder = pstr.null()
end
var view = data.view.media_gallery {
menu = pstr{'',0};
folders = pstr{'',0};
directory = pstr{'',0};
images = pstr{'',0};
pfx = pfx;
}
if folders.ct > 0 then
var fa = co:stra(128)
var fldr = co:pgetv('folder')
for i=0,folders.ct do
var ule = lib.html.urlenc(&co.srv.pool,folders(i), true) -- defer ule:free()
var san = lib.html.sanitize(&co.srv.pool,folders(i), true) -- defer san:free()
fa:lpush('<a href="'):ppush(pfx):lpush('/media?folder='):ppush(ule)
:lpush('">'):ppush(san):lpush('</a>')
lib.dbg('checking folder ',{fldr.ptr,fldr.ct},' against ',{folders(i).ptr,folders(i).ct})
if fldr:ref() and folders(i):cmp(fldr)
then folder = folders(i) lib.dbg('folder match ',{fldr.ptr,fldr.ct})
else folders(i):free()
end
end
fa:lpush('<hr>')
view.folders = fa:finalize()
folders:free()
end
if owner then
view.menu = '<a class="pos" href="/media/upload">upload</a><hr>'
end
var md = co.srv:artifact_enum_uid(uid, folder)
var gallery: lib.str.acc gallery:pool(&co.srv.pool,256)
var files: lib.str.acc files:pool(&co.srv.pool,256)
for i=0,md.ct do
var desc = lib.smackdown.html(&co.srv.pool,pstr{md(i)(0).desc,0}, true) --defer desc:free()
if lib.str.ncmp(md(i)(0).mime, 'image/', 6) == 0 then
gallery:lpush('<a class="thumb" href="'):ppush(pfx):lpush('/media/a/')
:push(md(i)(0).url,0):lpush('"><img src="/file/'):push(md(i)(0).url,0)
:lpush('"><div class="caption">'):ppush(desc)
:lpush('</div></a>')
else
var mime = lib.html.sanitize(&co.srv.pool,pstr{md(i)(0).mime,0}, true) --defer mime:free() --just in case
files:lpush('<a class="file" href="'):ppush(pfx):lpush('/media/a/')
:push(md(i)(0).url,0):lpush('"><span class="label">'):ppush(desc)
:lpush('</span> <span class="mime">'):ppush(mime)
:lpush('</span></a>')
end
md(i):free()
end
view.images = gallery:finalize()
view.directory = files:finalize()
if acc ~= nil then
view:append(acc)
else
var pg = view:poolstr(&co.srv.pool) -- defer pg:free()
co:stdpage([lib.srv.convo.page] {
title = 'media';
class = 'media manager';
cache = false;
body = pg;
})
end
--view.images:free()
--view.directory:free()
--if view.folders.ct > 0 then view.folders:free() end
if folder.ct > 0 then folder:free() end
if md:ref() then md:free() end
end
--if not owner then pfx:free() end
return end
::e404:: co:complain(404,'media not found','no such media exists on this server')
end
return render_media_gallery