parsav  media-gallery.t at [4ce1aab090]

File render/media-gallery.t artifact 3ee85e44c6 part of check-in 4ce1aab090


-- 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:uid2actor(uid)
	if ou == nil 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.origin ~= 0 then pa:lpush('@') end
			pa:push(ou.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
			defer art:free()
			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 class="button" 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 button" 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