added test + improved 3D wrapping of janusxr

This commit is contained in:
Leon van Kammen 2026-09-24 17:52:58 +02:00
parent 0b71c082a1
commit dd12979ae8
31 changed files with 144 additions and 62 deletions

1
.gitignore vendored
View file

@ -4,3 +4,4 @@ result
src/janusweb src/janusweb
janusweb* janusweb*
./myverse ./myverse
src/myverse/tronverse/tronverse-icosagallery

1
run.sh
View file

@ -1,4 +1,5 @@
#!/bin/sh #!/bin/sh
source ./.env source ./.env
rebuild rebuild
rm result/bin/xrforge.lua || true
DEBUG=1 result/bin/xrforge.com -c 0 "$@" --nobrowser DEBUG=1 result/bin/xrforge.com -c 0 "$@" --nobrowser

View file

@ -58,10 +58,15 @@ app.addExperience = function(experience, ino)
end end
end end
app.markViewable = function(exp) app.markViewable = function(exp, priority)
exp.view3D = true -- priority decides which 3D viewable wins (in case of multiple candidates inside same dir)
-- 0-100 markup experiences (high prio)
-- 100-200 3D model files
exp.view3D = priority or 300
if exp.parent.view3D == nil or exp.parent.view3D > priority then
exp.parent.redirect = exp.url -- mark parent to redirect to this standalone url instead (not glb assets e.g.) exp.parent.redirect = exp.url -- mark parent to redirect to this standalone url instead (not glb assets e.g.)
end end
end
-- api skeleton (implemented via soakbean's app.on(...)) -- api skeleton (implemented via soakbean's app.on(...))
app.set = function(k,v) end app.set = function(k,v) end

View file

@ -0,0 +1,6 @@
<fireboxroom>
<room skybox="false" selfavatar="false" showavatar="false" pos="0 0 1">
<object id="occludebox.glb" lighting="false" color_write="false" renderorder="1" position="0 0 -0.3"/>
<object id="Walk%20in%20the%20Woods%20by%20Don%20Carson%20-%2038m6Q1H12DU.glb" scale="10 10 10" pos="0 0 -8.3" renderorder="2"/>
</room>
</fireboxroom>

Binary file not shown.

View file

@ -1 +0,0 @@
{"assetId":"0dycp4HDxf4","authorId":"9Vkr0htmSzc","authorName":"coderofsalvation","createTime":"2026-09-15T13:03:05.314Z","description":"","displayName":"tronverse_floor #overlay #tronverse-icosagallery","formats":[{"formatComplexity":{},"formatType":"GLTF2","isCorsAllowed":true,"isPreferredForDownload":true,"isPreferredForGalleryViewer":true,"resources":[],"role":"USER_SUPPLIED_GLTF","root":{"contentType":"model\/gltf-binary","relativePath":"tronverse_floor.glb","url":"https:\/\/s3.us-east-005.backblazeb2.com\/icosa-gallery\/icosa\/28534\/755050994710086613\/GLTF2\/tronverse_floor.glb"}}],"isCurated":false,"isIcosaGalleryCompatible":true,"license":"CREATIVE_COMMONS_BY","licenseVersion":"4.0","name":"assets\/0dycp4HDxf4","thumbnail":{"relativePath":"preview_image.jpg","url":"https:\/\/s3.us-east-005.backblazeb2.com\/icosa-gallery\/icosa\/28534\/755050994710086613\/preview_image.jpg"},"triangleCount":0,"updateTime":"2026-09-16T11:21:33.683Z","url":"http:\/\/api.icosa.gallery\/v1\/assets\/0dycp4HDxf4","visibility":"PUBLIC"}

View file

@ -1 +0,0 @@
{"assetId":"C9J0_dyCzd8","authorId":"9Vkr0htmSzc","authorName":"coderofsalvation","createTime":"2026-09-15T18:22:06.894Z","description":"copy this asset as a starting point to paint into","displayName":"tronverse_parcel_empty #tronverse-icosagallery","formats":[{"formatComplexity":{},"formatType":"GLTF2","isCorsAllowed":true,"isPreferredForDownload":true,"isPreferredForGalleryViewer":true,"resources":[],"role":"USER_SUPPLIED_GLTF","root":{"contentType":"model\/gltf-binary","relativePath":"tronverse_parcel_empty.glb","url":"https:\/\/s3.us-east-005.backblazeb2.com\/icosa-gallery\/icosa\/28534\/755131280311452630\/GLTF2\/tronverse_parcel_empty.glb"}}],"isCurated":false,"isIcosaGalleryCompatible":true,"license":"CREATIVE_COMMONS_BY","licenseVersion":"4.0","name":"assets\/C9J0_dyCzd8","thumbnail":{"relativePath":"preview_image.jpg","url":"https:\/\/s3.us-east-005.backblazeb2.com\/icosa-gallery\/icosa\/28534\/755131280311452630\/preview_image.jpg"},"triangleCount":0,"updateTime":"2026-09-16T11:21:20.762Z","url":"http:\/\/api.icosa.gallery\/v1\/assets\/C9J0_dyCzd8","visibility":"PUBLIC"}

View file

@ -1 +0,0 @@
{"assetId":"igTGJIhJcSw","authorId":"9Vkr0htmSzc","authorName":"coderofsalvation","createTime":"2026-09-16T10:16:05.148Z","description":"","displayName":"tronverse_parcel3 #tronverse-icosagallery","formats":[{"formatComplexity":{},"formatType":"GLTF2","isCorsAllowed":true,"isPreferredForDownload":true,"isPreferredForGalleryViewer":true,"resources":[],"role":"USER_SUPPLIED_GLTF","root":{"contentType":"model\/gltf-binary","relativePath":"tronverse_parcel3.glb","url":"https:\/\/s3.us-east-005.backblazeb2.com\/icosa-gallery\/icosa\/28534\/755371354949157841\/GLTF2\/tronverse_parcel3.glb"}}],"isCurated":false,"isIcosaGalleryCompatible":true,"license":"CREATIVE_COMMONS_BY","licenseVersion":"4.0","name":"assets\/igTGJIhJcSw","thumbnail":{"relativePath":"preview_image.jpg","url":"https:\/\/s3.us-east-005.backblazeb2.com\/icosa-gallery\/icosa\/28534\/755371354949157841\/preview_image.jpg"},"triangleCount":0,"updateTime":"2026-09-16T11:20:41.832Z","url":"http:\/\/api.icosa.gallery\/v1\/assets\/igTGJIhJcSw","visibility":"PUBLIC"}

View file

@ -1 +0,0 @@
{"assetId":"mRU7wJh9BLQ","authorId":"9Vkr0htmSzc","authorName":"coderofsalvation","createTime":"2026-09-15T11:44:11.217Z","description":"","displayName":"tronverse_parcel1 #tronverse-icosagallery","formats":[{"formatComplexity":{},"formatType":"GLTF2","isCorsAllowed":true,"isPreferredForDownload":true,"isPreferredForGalleryViewer":true,"resources":[],"role":"USER_SUPPLIED_GLTF","root":{"contentType":"model\/gltf-binary","relativePath":"tronverse_parcel1.glb","url":"https:\/\/s3.us-east-005.backblazeb2.com\/icosa-gallery\/icosa\/28534\/755031138472297450\/GLTF2\/tronverse_parcel1.glb"}}],"isCurated":false,"isIcosaGalleryCompatible":true,"license":"CREATIVE_COMMONS_BY","licenseVersion":"4.0","name":"assets\/mRU7wJh9BLQ","thumbnail":{"relativePath":"preview_image.jpg","url":"https:\/\/s3.us-east-005.backblazeb2.com\/icosa-gallery\/icosa\/28534\/755031138472297450\/preview_image.jpg"},"triangleCount":0,"updateTime":"2026-09-16T11:21:48.917Z","url":"http:\/\/api.icosa.gallery\/v1\/assets\/mRU7wJh9BLQ","visibility":"PUBLIC"}

View file

@ -1 +0,0 @@
{"assetId":"oiIu1aNn6Ek","authorId":"9Vkr0htmSzc","authorName":"coderofsalvation","createTime":"2026-09-16T10:06:44.019Z","description":"","displayName":"tronverse_parcel2 #overlay #tronverse-icosagallery","formats":[{"formatComplexity":{},"formatType":"GLTF2","isCorsAllowed":true,"isPreferredForDownload":true,"isPreferredForGalleryViewer":true,"resources":[],"role":"USER_SUPPLIED_GLTF","root":{"contentType":"model\/gltf-binary","relativePath":"tronverse_parcel2.glb","url":"https:\/\/s3.us-east-005.backblazeb2.com\/icosa-gallery\/icosa\/28534\/755369001416131548\/GLTF2\/tronverse_parcel2.glb"}}],"isCurated":false,"isIcosaGalleryCompatible":true,"license":"CREATIVE_COMMONS_BY","licenseVersion":"4.0","name":"assets\/oiIu1aNn6Ek","thumbnail":{"relativePath":"preview_image.jpg","url":"https:\/\/s3.us-east-005.backblazeb2.com\/icosa-gallery\/icosa\/28534\/755369001416131548\/preview_image.jpg"},"triangleCount":0,"updateTime":"2026-09-16T11:20:54.904Z","url":"http:\/\/api.icosa.gallery\/v1\/assets\/oiIu1aNn6Ek","visibility":"PUBLIC"}

View file

@ -23,7 +23,7 @@ return {
and not urlpath:gsub(".*/",""):match("%.") -- no regular file with extension and not urlpath:gsub(".*/",""):match("%.") -- no regular file with extension
then then
local redirect = false local http_redirect = false
if not app.cache.url[ urlhash ] or util.count(req.params) > 0 then if not app.cache.url[ urlhash ] or util.count(req.params) > 0 then
local matchpath = urlpath local matchpath = urlpath
-- generate janusxr footer / rss for root url -- generate janusxr footer / rss for root url
@ -65,6 +65,8 @@ return {
end end
end) end)
-- see if we can get a viewable 3D item
local data = util.merge({ local data = util.merge({
janusurl = 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 = {}, items = {},
@ -82,20 +84,26 @@ return {
i=i+1 i=i+1
if v.view3D then if v.view3D then
local isMarkupExperience = function(v) local isMarkupExperience = function(v)
return v.janusxr and (v.janusxr.jml or v.janusxr.wrap) v = v or {}
return v.janusxr and v.janusxr.wrap
end end
-- *TODO* modularize this logic into plugins better
-- prioritize markup experience above binary 3D files as experience containers -- prioritize markup experience above binary 3D files as experience containers
if not data.item or (isMarkupExperience(v) and not isMarkupExperience(data.item)) then if data.item == nil or (isMarkupExperience(v) and not isMarkupExperience(data.item)) then
-- update referrer url -- update referrer url
data.referrer = util.baseURLify(v.view3D and (v.parent.parent and v.parent.parent.url) or v.parent.url) data.referrer = util.baseURLify(v.view3D and (v.parent.parent and v.parent.parent.url) or v.parent.url)
data.item = v data.item = v
data.title = data.item.title data.title = data.item.title
data.parent = v.parent data.parent = v.parent
data.janusurl = (v.janusxr and v.janusxr.wrap) and -- *TODO* modularize this logic into plugins better
app.opts.baseurl .. util.stripPath(v.parent.url) data.janusurl = (v.janusxr and v.janusxr.wrap) and app.opts.baseurl .. util.stripPath(v.url)
or -- if parent has redirect to item set, use parent url
app.opts.baseurl .. util.stripPath(v.url) if not data.janusurl or v.parent.redirect == v.url then
if v.janusxr and (v.janusxr.jml or v.janusxr.wrap and v.janusxr.wrap.aframe) then data.janusurl = app.opts.baseurl .. util.stripPath(v.parent.url)
end
if v.janusxr and v.janusxr.wrap and v.janusxr.wrap.file then
-- what to do here? no generated portals? -- what to do here? no generated portals?
data.janusxr = app.tpl( util.readfile(v.path), data ) data.janusxr = app.tpl( util.readfile(v.path), data )
end end
@ -108,14 +116,14 @@ return {
res.template = 'page/rss.xml' res.template = 'page/rss.xml'
end end
app.pub("dir", nil, {res=res,data=data, urlpath=urlpath, isroot=isroot, isdir=isdir}) app.pub("dir", nil, {res=res,data=data, urlpath=urlpath, isroot=isroot, isdir=isdir})
if not redirect then if not http_redirect then
app.cache.url[ urlhash ] = util.templateFile( res.template, data) app.cache.url[ urlhash ] = util.templateFile( res.template, data)
end end
end end
if redirect then if http_redirect then
print("REDIRECT! " .. redirect ) print("REDIRECT! " .. http_redirect )
res.status(303) res.status(303)
res.header('Location', redirect ) res.header('Location', http_redirect )
next() next()
else else
res.status(200) res.status(200)

View file

@ -61,6 +61,10 @@ end}
room = '' -- xrfragments 3D files dont need to be wrapped with room room = '' -- xrfragments 3D files dont need to be wrapped with room
end end
print(' <room skybox="true" pos="' .. pos .. '" showavatar="false" use_local_asset="' .. room .. '">') print(' <room skybox="true" pos="' .. pos .. '" showavatar="false" use_local_asset="' .. room .. '">')
if room == 'empty_floor' then
print(' <!-- helper to be able to walk/teleport -->')
print(' <object id="plane" color_write="false" rotation="90 0 0" collision_id="plane" scale="100 100 1" collision_scale="100 100 1"/>')
end
if defined(item) then if defined(item) then
print(' <object id="${item.url}"/>') print(' <object id="${item.url}"/>')
end end
@ -80,7 +84,7 @@ end}
local width = v.portal_width or tonumber( app.opts.plugin_global_portal_width ) local width = v.portal_width or tonumber( app.opts.plugin_global_portal_width )
local center = -((#itemsremote*width)/1.3) + (i*width) local center = -((#itemsremote*width)/1.3) + (i*width)
local url = v.url local url = v.url
local thumb = ' shader_id="defaultportal"' local thumb = ' shader_id="defaultportal" round="true"'
if #v.thumbnail > 0 then if #v.thumbnail > 0 then
thumb = ' thumb_id="imgremote' .. i .. '" ' thumb = ' thumb_id="imgremote' .. i .. '" '
end end
@ -99,7 +103,7 @@ end}
url = referrer, url = referrer,
title = app.opts.plugin_janusxr_portal_up, title = app.opts.plugin_janusxr_portal_up,
} }
print( app.plugin.janusxr.addPortal('parent',5, v, v.url, 0, 0, ' shader_id="defaultportal"', '0 -90 0', '0.2 0.2 0.2') ) print( app.plugin.janusxr.addPortal('parent',5, v, v.url, 0, 0, ' shader_id="defaultportal" round="true"', '0 -90 0', '0.2 0.2 0.2') )
end} end}
{if os.getenv('DEBUG') then {if os.getenv('DEBUG') then

View file

@ -21,23 +21,6 @@ app.on('scan_experience_file', function(exp)
local size = exp.file.attr:size() local size = exp.file.attr:size()
local wrap = false local wrap = false
if app.opts.plugin_janusxr_wrap_3dfile ~= "disabled"
and not (exp.tag.xrfragments and exp.tag.xrfragments.qualify) then -- dont wrap xrfragments experience
foreach( me.ext.object, function(k,ext)
if exp.path:lower():match("."..ext.."$") then
wrap = ext
end
end)
if wrap then
app.markViewable(exp)
exp.janusxr = { wrap = { object = true }}
exp.janusxr.room = me.wrapRoomAroundFile( exp )
app.pub("scan_experience_janusxr", nil, {exp=exp, item=item}) -- be nice to other plugins
app.addExperience( exp, exp.file.ino )
print("✅ └─ plugin/janusxr: wrapping " .. exp.path)
end
end
if (not me.isWrapFile(exp.path)) and size < 100000 then -- skip large binary files > 100kb if (not me.isWrapFile(exp.path)) and size < 100000 then -- skip large binary files > 100kb
local data = util.readfile( exp.file.fullpath) local data = util.readfile( exp.file.fullpath)
if data then if data then
@ -47,12 +30,18 @@ app.on('scan_experience_file', function(exp)
if title then if title then
exp.title = title:gsub("<.*","") exp.title = title:gsub("<.*","")
end end
app.markViewable(exp)
exp.janusxr = exp.janusxr or {} exp.janusxr = exp.janusxr or {}
exp.janusxr.wrap = nil -- erase previous 3D models
print("✅ └─ plugin/janusxr: " .. exp.file.name) print("✅ └─ plugin/janusxr: " .. exp.file.name)
if data:match(pattern_aframe) and app.opts.plugin_janusxr_wrap_aframe == 'enabled' then if data:match(pattern_aframe) and app.opts.plugin_janusxr_wrap_aframe == 'enabled' then
exp.janusxr.wrap = {aframe = true } exp.janusxr.wrap = {file = true }
app.markViewable(exp,50)
-- *TODO* assign room if no sky or equirect
print("✅ └─ plugin/janusxr: AFRAME markup detected") print("✅ └─ plugin/janusxr: AFRAME markup detected")
else
exp.janusxr.wrap = {redirect = true}
app.markViewable(exp,10)
print("✅ └─ plugin/janusxr: JML markup detected")
end end
app.pub("scan_experience_janusxr", nil, {exp=exp, item=item}) -- be nice to other plugins app.pub("scan_experience_janusxr", nil, {exp=exp, item=item}) -- be nice to other plugins
app.addExperience( exp, exp.file.ino ) app.addExperience( exp, exp.file.ino )
@ -61,12 +50,29 @@ app.on('scan_experience_file', function(exp)
-- symlink to directory -- symlink to directory
end end
end end
if exp.parent.redirect == nil and app.opts.plugin_janusxr_wrap_3dfile ~= "disabled"
and not (exp.tag.xrfragments and exp.tag.xrfragments.qualify) then -- dont wrap xrfragments experience
foreach( me.ext.object, function(k,ext)
if exp.path:lower():match("."..ext.."$") then
wrap = ext
end
end)
if wrap and not (exp.janusxr and exp.janusxr.jml ~= nil) then
app.markViewable(exp)
exp.janusxr = { wrap = { object = true }}
exp.janusxr.room = me.wrapRoomAroundFile( exp )
app.pub("scan_experience_janusxr", nil, {exp=exp, item=item}) -- be nice to other plugins
app.addExperience( exp, exp.file.ino )
print("✅ └─ plugin/janusxr: wrapping " .. exp.path)
end
end
end) end)
app.on('set', function(k,v) end) app.on('set', function(k,v) end)
-- this registers the plugin UI -- this registers the plugin UI
local rooms = { [""]="empty",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 rooms = { [""]="empty",empty_plane="empty (+floorcollider)",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 = { local plugin = {
name = "JanusXR", name = "JanusXR",
@ -225,8 +231,8 @@ local plugin = {
if v.key == 'app.opts.plugin_janusxr_portalroom' then if v.key == 'app.opts.plugin_janusxr_portalroom' then
local ordered = {} local ordered = {}
foreach( v.values, function(k,v) foreach( v.values, function(k,v)
if not v:match("random") then if not v:match("random") and not v:match("empty") then
table.insert(ordered,v) table.insert(ordered,k)
end end
end) end)
table.sort(ordered) -- ensure same order table.sort(ordered) -- ensure same order

View file

@ -15,7 +15,7 @@ local grid = {
local index = 0 local index = 0
for i, v in pairs(items) do for i, v in pairs(items) do
local url = v.redirect and v.redirect or v.url local url = v.redirect and v.redirect or v.url
local overlay = v.title:match('#overlay') and true or false local overlay = v.title:match('overlay') and true or false
-- Position current item -- Position current item
local pos = { local pos = {
x = overlay and 0 or x * gridsize, x = overlay and 0 or x * gridsize,

View file

@ -24,7 +24,7 @@ local function scanForOpenBrush(exp)
if not exp.parent.janusxr then if not exp.parent.janusxr then
exp.parent.janusxr = {} exp.parent.janusxr = {}
end end
exp.parent.janusxr.room = app.opts.plugin_openbrush_wrap_room exp.parent.janusxr.room = app.opts[ "plugin_openbrush_wrap_room_" .. app.opts.plugin_openbrush_layout ] or 'empty'
exp.parent.portal_width = tonumber( app.opts.plugin_openbrush_portal_width ) exp.parent.portal_width = tonumber( app.opts.plugin_openbrush_portal_width )
exp.parent.grid_size = tonumber( app.opts.plugin_openbrush_grid_size ) exp.parent.grid_size = tonumber( app.opts.plugin_openbrush_grid_size )
exp.parent.layout = app.opts.plugin_openbrush_layout exp.parent.layout = app.opts.plugin_openbrush_layout
@ -58,13 +58,6 @@ local plugin = {
-- { label = "resync now!", href="/reset" } -- { label = "resync now!", href="/reset" }
--}, --},
opts = { opts = {
{
key='app.opts.plugin_openbrush_wrap_room',
title='Wrap VR space',
info='render 3D files in <a href="https://coderofsalvation.github.io/janus-guide/#/build/room" target="_blank">janusxr.xml</a> room',
default="",
values= app.plugin.janusxr.opts[4].values -- reuse rooms from janusxr plugin
},
{ {
key='app.opts.plugin_openbrush_layout', key='app.opts.plugin_openbrush_layout',
title='Layout assets', title='Layout assets',
@ -72,6 +65,20 @@ local plugin = {
default="grid", default="grid",
values={portals="As portals", grid="As grid"} values={portals="As portals", grid="As grid"}
}, },
{
key='app.opts.plugin_openbrush_wrap_room_portals',
title='grid: wrap',
info='render 3D files in <a href="https://coderofsalvation.github.io/janus-guide/#/build/room" target="_blank">janusxr.xml</a> room',
default="room_plane",
values= app.plugin.janusxr.opts[4].values -- reuse rooms from janusxr plugin
},
{
key='app.opts.plugin_openbrush_wrap_room_grid',
title='portals: wrap',
info='render 3D files in <a href="https://coderofsalvation.github.io/janus-guide/#/build/room" target="_blank">janusxr.xml</a> room',
default="empty_floor",
values= app.plugin.janusxr.opts[4].values -- reuse rooms from janusxr plugin
},
{ {
key='app.opts.plugin_openbrush_layout_grid_size', key='app.opts.plugin_openbrush_layout_grid_size',
title='Grid size', title='Grid size',

View file

@ -45,7 +45,7 @@ app.on('scan_experience_file', function(exp)
href = hasHref href = hasHref
} }
if exp.tag.xrfragments.qualify then if exp.tag.xrfragments.qualify then
app.markViewable(exp) app.markViewable(exp, 100)
print("✅ └─ plugin/xrfragments: detected xrfragments experience") print("✅ └─ plugin/xrfragments: detected xrfragments experience")
end end
if exp.tag.xrfragments.href then if exp.tag.xrfragments.href then

View file

@ -9,8 +9,9 @@ lust.queueServerRequest = util.queueServerRequest
--require('test/plugin_git')(lust) --require('test/plugin_git')(lust)
--require('test/plugin_diskscan')(lust) --require('test/plugin_diskscan')(lust)
--require('test/plugin_xrfragment')(lust) --require('test/plugin_xrfragment')(lust)
require('test/plugin_openbrush')(lust) require('test/plugin_janusxr')(lust)
require('test/util')(lust) --require('test/plugin_openbrush')(lust)
--require('test/util')(lust)
if lust.errors == 0 then if lust.errors == 0 then
print("✅ all tests passed") print("✅ all tests passed")

View file

@ -0,0 +1,45 @@
return function(lust)
local describe, it, expect = lust.describe, lust.it, lust.expect
describe('src/plugin/janusxr.lua', function()
describe('ℹ️ wrap 3D file', function() -- Can be nested
it('detect & serve to iframe', function()
-- *TODO*
end)
end)
describe('ℹ️ wrap AFRAME file', function() -- Can be nested
it('detect & serve to iframe', function()
-- *TODO*
end)
end)
describe('ℹ️ wrap JML', function() -- Can be nested
it('detect & serve to iframe', function()
app.init()
app.use( require('page/dir').middleware )
app.use( app.response() )
app.on('response', function(opts)
expect( opts.res._body:match('janus.url=/myverse/janusxr_tutorial/arwindow') ).to.be.truthy()
end)
foreach(app.cache.items, function(k,exp)
if exp.url:match("arwindow") then
if exp.url:match("arwindow$") then
expect( exp.redirect:match("index.html$") ).to.be.truthy()
lust.queueServerRequest('GET', exp.url, nil, nil, nil, nil, nil, 8080 )
app.run()
end
end
end)
end)
end)
end)
end

View file

@ -32,12 +32,15 @@ download(){
janusweb(){ janusweb(){
set -x set -x
test -d janusweb || {
version=1.7.5 version=1.7.5
test -f janusweb-${version}.tar.gz || { test -f janusweb-${version}.tar.gz || {
wget "https://github.com/coderofsalvation/janusweb/releases/download/v${version}-rc/janusweb-${version}.tar.gz" wget "https://github.com/coderofsalvation/janusweb/releases/download/v${version}-rc/janusweb-${version}.tar.gz"
} }
test -d janusweb-${version} || tar -xvf janusweb-${version}.tar.gz test -d janusweb-${version} || tar -xvf janusweb-${version}.tar.gz
test -d src/janusweb || cp -Lr janusweb-${version} src/janusweb mv janusweb-${version} janusweb
}
test -d src/janusweb || cp -Lr janusweb src/janusweb
} }
"$@" "$@"