fixed symlink & referrer stuff
This commit is contained in:
parent
26d1bfbd1e
commit
3981800e42
12 changed files with 128 additions and 69 deletions
|
|
@ -1,8 +1,8 @@
|
|||
-H
|
||||
Access-Control-Allow-Origin: *
|
||||
-H
|
||||
Access-Control-Allow-Method: GET, OPTIONS
|
||||
Access-Control-Allow-Method: GET, HEAD, OPTIONS
|
||||
-H
|
||||
Allow: GET, POST, OPTIONS
|
||||
Allow: GET, HEAD, POST, OPTIONS
|
||||
-D
|
||||
.
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ app = require("soakbean") {
|
|||
generate = {file="cmd/generate.lua", info="generate www-folder with XR experiences"},
|
||||
test = {file="cmd/test.lua", info="run testsuite (selftest)"}
|
||||
},
|
||||
|
||||
addPlugin = function(file)
|
||||
local p = require(file)
|
||||
table.insert(app.plugin,p)
|
||||
|
|
@ -40,6 +41,14 @@ app = require("soakbean") {
|
|||
end)
|
||||
app.set('app.opts', app.opts)
|
||||
return p
|
||||
end,
|
||||
|
||||
addExperience = function(experience, ino)
|
||||
if app.cache.items[ino] then -- handle duplicate symlinks, symlinks to symlinks e.g.
|
||||
app.cache.items[ino .. ' ' .. experience.parent.id ] = experience
|
||||
else
|
||||
app.cache.items[ino] = experience
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
|
|
@ -78,9 +87,9 @@ print = function(...) Log(kLogInfo, ... or "''") end -- nice redbean logging fro
|
|||
-- init URL router
|
||||
app.url['^/data'] = '/data.lua' -- setup custom file endpoint
|
||||
|
||||
app.use( require('middleware/onlyGET')({exclude={'^/admin'}}) ) -- we are staticwebgen-first server-last
|
||||
app.use( app.plugin.global.middleware.homepage_2D_or_3D )
|
||||
app.url['^/admin[/]?$'] = '/page/admin/index.lua'
|
||||
app.use( require('middleware/onlyGET')({exclude={'^/admin'}}) ) -- we are staticwebgen-first server-last
|
||||
|
||||
app.get('^/design[/]?$', util.pagerender('page/design.html'))
|
||||
app.get('^/about[/]?$', util.pagerender('page/about.html'))
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ util.template = function(content,data)
|
|||
-- set fallback vars
|
||||
mdata.urlpath = util.baseURLify( GetPath() )
|
||||
mdata.url = mdata.url or mdata.urlpath
|
||||
mdata.janusurl = mdata.janusurl or mdata.urlpath
|
||||
mdata.title = mdata.title or app.opts.subtitle
|
||||
mdata.header_include = mdata.header_include or ''
|
||||
mdata.footerlinks = {}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ return function(opts)
|
|||
opts = opts or {exclude={"^/admin"}}
|
||||
return function(req,res,next)
|
||||
local pass = false
|
||||
if req.method == "GET" then
|
||||
if req.method == "GET" or req.method == "HEAD" then
|
||||
pass = true
|
||||
else
|
||||
foreach(opts.exclude, function(k,path)
|
||||
|
|
|
|||
|
|
@ -57,9 +57,7 @@ end
|
|||
|
||||
app.on('set', function(k,v) -- clear url cache
|
||||
if k:match("app.opts") then -- after (admin) updates to app.opts.*
|
||||
foreach( app.cache.url, function(k,v)
|
||||
app.cache.url = {}
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,7 @@ end}
|
|||
|
||||
function getURL(url)
|
||||
if app.arg[1] == 'generate' or url:match("://") then
|
||||
url = 'janusweb/index.html#janus.url=' ..
|
||||
EscapeFragment( url ) .. '&janus.referrer=' .. util.getURL(urlpath )
|
||||
url = '?view=3D#janus.url=' .. EscapeFragment( url )
|
||||
url = util.baseURLify(url)
|
||||
else
|
||||
url = util.stripPath( url )
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ return {
|
|||
local matchpath = urlpath
|
||||
if urlpath == '/' then matchpath = rootpath end -- generate janusxr footer for root url
|
||||
foreach( app.cache.items, function(k,v)
|
||||
print("URL=" ..v.url)
|
||||
if req.authenticated or app.plugin.moderation.isAllowed(v) then
|
||||
if v.parent then
|
||||
-- trace( "path = " .. util.stripPath(v.path) .. " " ..
|
||||
|
|
@ -57,7 +58,7 @@ return {
|
|||
end)
|
||||
|
||||
local data = util.merge({
|
||||
url = req.param.url, -- query hint to render janus.url in iframe (index.html)
|
||||
janusurl = req.param.url, -- query hint to render janus.url in iframe (index.html)
|
||||
items = {},
|
||||
isroot = isroot,
|
||||
referrer = referrer,
|
||||
|
|
@ -71,7 +72,7 @@ return {
|
|||
i=i+1
|
||||
if v.view3D then
|
||||
local isMarkupExperience = function(v)
|
||||
return v.janusxr and (v.janusxr.jml or v.janusxr.aframe)
|
||||
return v.janusxr and (v.janusxr.jml or v.janusxr.wrap)
|
||||
end
|
||||
-- prioritize markup experience above binary 3D files as experience containers
|
||||
if not data.item or (isMarkupExperience(v) and not isMarkupExperience(data.item)) then
|
||||
|
|
@ -80,9 +81,11 @@ return {
|
|||
data.item = v
|
||||
data.title = data.item.title
|
||||
data.parent = v.parent
|
||||
data.url = app.opts.baseurl .. util.stripPath(v.url) -- because we are running in iframe
|
||||
-- .. EscapeFragment( (v.url:match("#") and "&" or "#" ) .. 'janus.referrer=' .. EscapeFragment(v.referrer) )
|
||||
if v.janusxr and (v.janusxr.jml or v.janusxr.aframe) then
|
||||
data.janusurl = (v.janusxr and v.janusxr.wrap) and
|
||||
app.opts.baseurl .. util.stripPath(v.parent.url)
|
||||
or
|
||||
app.opts.baseurl .. util.stripPath(v.url)
|
||||
if v.janusxr and (v.janusxr.jml or v.janusxr.wrap and v.janusxr.wrap.aframe) then
|
||||
-- what to do here? no generated portals?
|
||||
data.janusxr = app.tpl( util.readfile(v.path), data )
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ ${header}
|
|||
<div></div>
|
||||
</div>
|
||||
|
||||
<iframe border="0" frameborder="0" src="janusweb/index.html#janus.url=${url}&janus.referrer=${referrer}" id="viewer"></iframe>
|
||||
<iframe border="0" frameborder="0" src="janusweb/index.html#janus.url=${janusurl}&janus.referrer=${referrer}" id="viewer"></iframe>
|
||||
|
||||
{if defined(item) and item.parent and item.parent.info then
|
||||
print([[
|
||||
|
|
@ -45,6 +45,10 @@ end}
|
|||
}, 1000 )
|
||||
});
|
||||
});
|
||||
|
||||
// reroute janus.url to iframe if needed
|
||||
let params = new URLSearchParams( document.location.href.replace(/.*#/,'') )
|
||||
if( params?.get('janus.url') ) iframe.src = 'janusweb/index.html#janus.url=' + encodeURIComponent( params.get('janus.url') )
|
||||
</script>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -40,17 +40,21 @@ end}
|
|||
end}
|
||||
</assets>
|
||||
{if true then
|
||||
local room = app.opts.plugin_janusxr_portalroom
|
||||
if defined(item) and item.janusxr and item.janusxr.room then
|
||||
room = item.janusxr.room
|
||||
local room = ''
|
||||
pos = '0 0 0'
|
||||
if not defined(item) and defined(items) then
|
||||
room = app.opts.plugin_janusxr_portalroom
|
||||
end
|
||||
if room == 'random' then room = app.plugin.janusxr.getRandomRoom() end
|
||||
if defined(item) and item.tag.xrfragments and item.tag.xrfragments.qualify then
|
||||
if defined(item) and item.janusxr and item.janusxr.wrap then
|
||||
pos = '0 0 2'
|
||||
room = app.plugin.janusxr.wrapRoomAroundFile(item)
|
||||
end
|
||||
if defined(item) and item.tag.xrfragments and item.tag.xrfragments.href then
|
||||
room = '' -- xrfragments 3D files dont need to be wrapped with room
|
||||
end
|
||||
print(' <room skybox="true" showavatar="false" use_local_asset="' .. room .. '">')
|
||||
print(' <room skybox="true" pos="' .. pos .. '" showavatar="false" use_local_asset="' .. room .. '">')
|
||||
if defined(item) then
|
||||
print(' <object id="${url}"/>')
|
||||
print(' <object id="${item.url}"/>')
|
||||
end
|
||||
end}
|
||||
<light js_id="dan9-janus:light/light_cone_angle=0-6" pos="0 3 2" collision_trigger="false" />
|
||||
|
|
@ -87,6 +91,10 @@ end}
|
|||
local width = 3.2
|
||||
local center = -((#itemsremote*width)/1.3) + (i*width)
|
||||
local url = v.url
|
||||
--if url:match("://") then
|
||||
-- url = url .. ( url:match("#") and '&' or '#' ) .. 'janus.referrer=' ..
|
||||
-- EscapeFragment( util.getURL() )
|
||||
--end
|
||||
local thumb = ' shader_id="defaultportal"'
|
||||
if #v.thumbnail > 0 then
|
||||
thumb = ' thumb_id="imgremote' .. i .. '" '
|
||||
|
|
@ -106,10 +114,10 @@ end}
|
|||
url = referrer,
|
||||
title = app.opts.plugin_janusxr_portal_up,
|
||||
}
|
||||
addPortal('parent',4, v, v.url, 0, 0, ' shader_id="defaultportal"', '0 -90 0', '0.2 0.2 0.2')
|
||||
addPortal('parent',5, v, v.url, 0, 0, ' shader_id="defaultportal"', '0 -90 0', '0.2 0.2 0.2')
|
||||
end}
|
||||
|
||||
<object id="cube" rotation="0 0 0" position="0 0 0" scale="2 0.1 2"/> <!-- something to stand on -->
|
||||
<object id="cube" rotation="0 45 0" pos="${pos}" scale="2 0.1 2"/> <!-- something to stand on -->
|
||||
{if not defined(item) then
|
||||
print('${janusxr_jml_deco}')
|
||||
end}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ return {
|
|||
shouldHideFile = function(name)
|
||||
return name == ".." -- parent
|
||||
or name == "util" -- repository
|
||||
or name:match("^%.") -- hidden
|
||||
or name:match("^%.[a-zA-Z0-9_-]") -- hidden
|
||||
or name == "src" -- repository
|
||||
or name == "result" -- repository
|
||||
end,
|
||||
|
|
@ -46,7 +46,7 @@ return {
|
|||
local me = app.plugin.diskscan
|
||||
local seen = {symlinks={}}
|
||||
-- ensure rootdir as experience
|
||||
app.cache.items[ scandir ] = {
|
||||
app.addExperience({
|
||||
path = scandir,
|
||||
url = "/" .. util.stripPath(scandir),
|
||||
name = scandir:gsub(".*/",""),
|
||||
|
|
@ -54,7 +54,7 @@ return {
|
|||
title = scandir:gsub(".*/",""):gsub("-"," "),
|
||||
file = { ino = scandir },
|
||||
id = scandir
|
||||
}
|
||||
},scandir)
|
||||
me.scanDir(scandir, nil, seen )
|
||||
-- deal with (circular) symlinks
|
||||
foreach( seen.symlinks, function(ino,experience)
|
||||
|
|
@ -65,8 +65,8 @@ return {
|
|||
print("✅ └─ plugin/diskscan: detected symlink..creating portal")
|
||||
experience.file = refItem.file
|
||||
experience.portal = refItem
|
||||
app.pub("scan_experience", nil, experience)
|
||||
app.cache.items[experience.id] = experience
|
||||
app.pub("scan_experience" .. (experience.dir and '' or '_file') , nil, experience)
|
||||
app.addExperience(experience,ino)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
|
@ -100,26 +100,34 @@ return {
|
|||
}
|
||||
experience.parent = parent
|
||||
|
||||
if seen[ino] then return end -- dont process dirs/files twice
|
||||
|
||||
if (kind == unix.DT_LNK) then
|
||||
experience.symlink = true
|
||||
local stat, err = unix.stat(fullpath)
|
||||
if stat then
|
||||
experience.id_target = stat:ino()
|
||||
experience.id_target = stat:ino() -- stat follows symlink by default
|
||||
local realpath = unix.realpath(fullpath)
|
||||
state,err = unix.opendir(realpath)
|
||||
if not err then
|
||||
experience.symlink = true
|
||||
experience.dir = true
|
||||
state:close()
|
||||
end
|
||||
seen.symlinks[ ino ] = experience
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
--local already_seen = seen[ino] and seen[ino].parent.file.ino == experience.parent.file.ino and true or false -- process once
|
||||
--if already_seen and not experience.symlink then return end
|
||||
|
||||
-- found directory
|
||||
if (kind == unix.DT_DIR and kind ~= unix.DT_LNK)
|
||||
and not me.shouldHideFile(name) then
|
||||
seen[ino] = experience -- prevent recursion with symlinks
|
||||
print("✅ ".. fullpath .. " " ..ino)
|
||||
if not me.shouldHideFile(name) and
|
||||
( (kind == unix.DT_DIR and kind ~= unix.DT_LNK) or experience.dir )
|
||||
then
|
||||
print("✅ ".. fullpath )
|
||||
experience.dir = true
|
||||
experience.portal3D = true -- can be viewed as 3d portal
|
||||
app.pub("scan_experience", nil, experience)
|
||||
app.cache.items[ino] = experience
|
||||
app.addExperience(experience,ino)
|
||||
-- check for directory thumbnail sidecarfile
|
||||
local thumbExt = {"png","jpg","webp"}
|
||||
foreach( thumbExt, function(k,ext)
|
||||
|
|
@ -136,14 +144,18 @@ return {
|
|||
end
|
||||
|
||||
---- found file
|
||||
if (kind ~= unix.DT_DIR and kind ~= unix.DT_LNK)
|
||||
and not me.shouldHideFile(name) then
|
||||
seen[ino] = experience.file -- prevent recursion with symlinks
|
||||
if not me.shouldHideFile(name) and
|
||||
( (kind ~= unix.DT_DIR and kind ~= unix.DT_LNK) or not experience.dir )
|
||||
then
|
||||
trace("ℹ️ ".. fullpath)
|
||||
experience.tag.file = true
|
||||
app.pub("scan_experience_file", nil, experience)
|
||||
local size = attr:size()
|
||||
end
|
||||
|
||||
-- remember file/parent relationship
|
||||
seen[ino] = experience
|
||||
|
||||
end
|
||||
|
||||
local dref, derr;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ app.on('dir', function(opts)
|
|||
if #app.opts.plugin_janusxr_random_objects > 0 and
|
||||
#app.opts.plugin_janusxr_random_colors > 0 then
|
||||
opts.data.janusxr_jml_deco = app.plugin.janusxr.getRandomDeco(7,50,hash,0,30) ..
|
||||
app.plugin.janusxr.getRandomDeco(7,50,hash .. hash,30,30)
|
||||
app.plugin.janusxr.getRandomDeco(7,50, "2" .. hash,30,30)
|
||||
end
|
||||
end)
|
||||
|
||||
|
|
@ -31,10 +31,8 @@ app.on('scan_experience_file', function(exp)
|
|||
end)
|
||||
if wrap then
|
||||
exp.view3D = true
|
||||
exp.janusxr = {
|
||||
room = app.opts.plugin_janusxr_wrap_3dfile
|
||||
}
|
||||
app.cache.items[ exp.file.ino ] = exp
|
||||
exp.janusxr = { wrap = { object = true }}
|
||||
app.addExperience( exp, exp.file.ino )
|
||||
print("✅ └─ plugin/janusxr: wrapping " .. exp.path)
|
||||
end
|
||||
end
|
||||
|
|
@ -49,13 +47,13 @@ app.on('scan_experience_file', function(exp)
|
|||
exp.title = title:gsub("<.*","")
|
||||
end
|
||||
app.pub("scan_experience_janusxr", nil, {exp=exp, item=item}) -- be nice to other plugins
|
||||
app.cache.items[ exp.file.ino ] = exp
|
||||
app.addExperience( exp, exp.file.ino )
|
||||
exp.view3D = true
|
||||
exp.parent.redirect = exp.url -- mark parent to redirect to this standalone url instead (not glb assets e.g.)
|
||||
exp.janusxr = {}
|
||||
print("✅ └─ plugin/janusxr: " .. exp.file.name)
|
||||
if data:match(pattern_aframe) and app.opts.plugin_janusxr_wrap_aframe == 'enabled' then
|
||||
exp.janusxr.aframe = true
|
||||
exp.janusxr.wrap = {aframe = true }
|
||||
print("✅ └─ plugin/janusxr: AFRAME markup detected")
|
||||
end
|
||||
end
|
||||
|
|
@ -68,7 +66,7 @@ end)
|
|||
app.on('set', function(k,v) end)
|
||||
|
||||
-- this registers the plugin UI
|
||||
local rooms = {random="random room",room_plane="wirefloor",room1="room1",room2="room2",room3="room3",room4="room4",room5="room5",room6="room6",room7="room7"}
|
||||
local rooms = {random="random room",randomurl="random room (URL-deterministic)",room_plane="wirefloor",room1="room1",room2="room2",room3="room3",room4="room4",room5="room5",room6="room6",room7="room7"}
|
||||
|
||||
local plugin = {
|
||||
name = "JanusXR",
|
||||
|
|
@ -95,29 +93,29 @@ local plugin = {
|
|||
key='app.opts.plugin_janusxr_wrap_3dfile',
|
||||
title='VR wrap 3D file',
|
||||
info='render 3D files in <a href="https://coderofsalvation.github.io/janus-guide/#/build/room" target="_blank">janusxr.xml</a> room',
|
||||
default="room_plane",
|
||||
default="randomurl",
|
||||
values=util.merge(rooms,{disabled="-- disabled --"})
|
||||
},
|
||||
{
|
||||
key='app.opts.plugin_janusxr_wrap_image',
|
||||
title='VR wrap images',
|
||||
info='render images in <a href="https://coderofsalvation.github.io/janus-guide/#/build/room" target="_blank">janusxr.xml</a> room',
|
||||
default="room_plane",
|
||||
default="randomurl",
|
||||
values=util.merge(rooms,{disabled="-- disabled --"})
|
||||
},
|
||||
{
|
||||
key='app.opts.plugin_janusxr_wrap_video',
|
||||
title='VR wrap videos',
|
||||
info='render videos in <a href="https://coderofsalvation.github.io/janus-guide/#/build/room" target="_blank">janusxr.xml</a> room',
|
||||
default="room_plane",
|
||||
default="randomurl",
|
||||
values=util.merge(rooms,{disabled="-- disabled --"})
|
||||
},
|
||||
{
|
||||
key='app.opts.plugin_janusxr_wrap_aframe',
|
||||
title='AFRAME support',
|
||||
info='render <a href="https://aframe.io">AFRAME</a> (geometry) markup when detected in URLs',
|
||||
default="enabled",
|
||||
values={enabled="enabled",disabled="disabled"}
|
||||
default="room_plane",
|
||||
values=util.merge(rooms,{disabled="-- disabled --"})
|
||||
},
|
||||
{
|
||||
key='app.opts.plugin_janusxr_portalroom',
|
||||
|
|
@ -138,7 +136,7 @@ local plugin = {
|
|||
key='app.opts.plugin_janusxr_random_objects',
|
||||
title='Random objects',
|
||||
info="Random object id's in portal rooms",
|
||||
default="capsule cone cube cylinder pyramid sphere torus",
|
||||
default="capsule cone cylinder pyramid sphere torus",
|
||||
placeholder="capsule cone cylinder pyramid sphere torus",
|
||||
values="",
|
||||
},
|
||||
|
|
@ -174,21 +172,54 @@ local plugin = {
|
|||
}
|
||||
},
|
||||
|
||||
getRandomRoom = function()
|
||||
wrapRoomAroundFile = function(item)
|
||||
local room = ''
|
||||
if item.janusxr.wrap.object then
|
||||
room = app.opts.plugin_janusxr_wrap_3dfile
|
||||
end
|
||||
if room == 'random' then
|
||||
room = app.plugin.janusxr.getRandomRoom()
|
||||
end
|
||||
if room == 'randomurl' then
|
||||
room = app.plugin.janusxr.getRandomRoom(item.url)
|
||||
end
|
||||
return room
|
||||
end,
|
||||
|
||||
getRandomRoom = function(url)
|
||||
local me = app.plugin.janusxr
|
||||
local room= ''
|
||||
math.randomseed(os.time())
|
||||
foreach( me.opts, function(k,v)
|
||||
if v.key == 'app.opts.plugin_janusxr_portalroom' then
|
||||
local ordered = {}
|
||||
foreach( v.values, function(k,v) table.insert(ordered,v) end)
|
||||
foreach( v.values, function(k,v)
|
||||
if not v:match("random") then
|
||||
table.insert(ordered,v)
|
||||
end
|
||||
end)
|
||||
table.sort(ordered) -- ensure same order
|
||||
if url then
|
||||
room = ordered[ me.hash_string_to_number(url) % #ordered ]
|
||||
else
|
||||
room = ordered[ math.random( #ordered ) ]
|
||||
end
|
||||
end
|
||||
end)
|
||||
return room
|
||||
end,
|
||||
|
||||
hash_string_to_number = function(str)
|
||||
local hash = 5381
|
||||
for i = 1, #str do
|
||||
local char = string.byte(str, i)
|
||||
hash = (hash * 33 + char) % 2147483647
|
||||
end
|
||||
return hash
|
||||
end,
|
||||
|
||||
getRandomDeco = function(num_objects, radius, seed_string, y, scale)
|
||||
local me = app.plugin.janusxr
|
||||
num_objects = num_objects or 6
|
||||
y = y or 0
|
||||
radius = radius or 2 -- Configurable distance from (0, 0, 0)
|
||||
|
|
@ -196,18 +227,12 @@ local plugin = {
|
|||
local JML = ''
|
||||
local colors = util.split( app.opts.plugin_janusxr_random_colors, ' ')
|
||||
local ids = util.split( app.opts.plugin_janusxr_random_objects, ' ')
|
||||
table.sort(colors) -- ensure same order
|
||||
table.sort(ids) -- ensure same order
|
||||
|
||||
local function hash_string_to_number(str)
|
||||
local hash = 5381
|
||||
for i = 1, #str do
|
||||
local char = string.byte(str, i)
|
||||
hash = (hash * 33 + char) % 2147483647
|
||||
end
|
||||
return hash
|
||||
end
|
||||
local index = {
|
||||
color= hash_string_to_number(seed_string) % #colors,
|
||||
id = hash_string_to_number(seed_string) % #ids
|
||||
color= me.hash_string_to_number(seed_string) % #colors,
|
||||
id = me.hash_string_to_number(seed_string) % #ids
|
||||
}
|
||||
|
||||
for i = 1, num_objects do
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ app.on('scan_experience_file', function(exp)
|
|||
-- finally insert if viewable
|
||||
if exp.view3D then
|
||||
print("✅ └─ plugin/xrfragments: marking as 3D viewable")
|
||||
app.cache.items[ exp.file.ino ] = exp
|
||||
app.addExperience(exp, exp.file.ino)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue