openbrush admin tweak + added customized index.jml

This commit is contained in:
Leon van Kammen 2026-09-04 16:34:57 +02:00
parent cbe5c021d7
commit e1ea486212
7 changed files with 160 additions and 11 deletions

View file

@ -79,6 +79,7 @@ app.plugin.peertube = app.addPlugin('plugin/peertube')
app.plugin.git = app.addPlugin('plugin/git')
app.plugin.webhook = app.addPlugin('plugin/webhook')
app.plugin.archive = app.addPlugin('plugin/archive')
app.plugin.openbrush = app.addPlugin('plugin/openbrush')
--app.plugin.scheduler = app.addPlugin('plugin/scheduler') -- should always be second last
app.plugin.staticwebgen = app.addPlugin('plugin/staticwebgen') -- should always be last

View file

@ -297,7 +297,7 @@ img.icon{ display:none; }
.info{
background:#224;
padding:10px 20px;
padding:20px 30px;
overflow:clip;
}

BIN
src/img/openbrush.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View file

@ -31,7 +31,9 @@ return {
matchpath = rootpath
end
foreach( app.cache.items, function(k,v)
if req.authenticated or app.plugin.moderation.isAllowed(v) then
if req.authenticated or
(app.plugin.moderation.isAllowed(v) and not app.plugin.janusxr.isWrapFile(v.path))
then
if v.parent then
-- trace( "path = " .. util.stripPath(v.path) .. " " ..
-- "parent = " .. util.stripPath(v.parent.path) .. " " ..
@ -50,6 +52,7 @@ return {
if v.dir or v.view3D then
local parent = app.cache.items[ v.parent.id ]
res.items[ v.id ] = v
res.itemdir = v
res.parent = parent
end
if isroot then
@ -83,7 +86,7 @@ return {
-- prioritize markup experience above binary 3D files as experience containers
if not data.item or (isMarkupExperience(v) and not isMarkupExperience(data.item)) then
-- update referrer url
data.referrer = util.baseURLify(v.view3D 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.title = data.item.title
data.parent = v.parent

View file

@ -1,4 +1,6 @@
{if true then
sidecarfile = (parent and parent.path or '') .. '/' .. app.opts.plugin_janusxr_wrap_custom
hasSidecarfile = util.fileExist(sidecarfile) and true or false
showfediportals = app.opts.plugin_federation_strategy == 'always' or
(app.opts.plugin_federation_strategy == 'homepage' and urlpath == '/')
@ -49,7 +51,7 @@ end}
pos = '0 0 2'
room = app.plugin.janusxr.wrapRoomAroundFile(item)
end
if defined(item) and item.tag.xrfragments and item.tag.xrfragments.href then
if hasSidecarfile or (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" pos="' .. pos .. '" showavatar="false" use_local_asset="' .. room .. '">')
@ -148,10 +150,19 @@ end}
end}
<object id="cube" rotation="0 45 0" pos="${pos}" scale="2 0.1 2"/> <!-- something to stand on -->
{if not defined(item) then
{if not defined(item) and not hasSidecarfile then
print('${janusxr_jml_deco}')
end}
${opts.plugin_janusxr_jml}
{if hasSidecarfile then
print(' <!-- inserted by XRForge server: ' .. app.opts.plugin_janusxr_wrap_custom .. ' -->')
print(' <link url="' .. parent.path .. '/' .. app.opts.plugin_janusxr_wrap_custom .. '" url_pos="0 0 0" pos="0 0 1" url_scale="1 1 1" js_id="index_jml" auto_load="true" />')
end}
{if #opts.plugin_janusxr_jml > 0 then
print(' <!-- inserted by XRForge server: janusxr admin (Extra JML) -->')
print(' ' .. app.opts.plugin_janusxr_jml)
end}
</room>
</fireboxroom>

View file

@ -5,7 +5,6 @@ local pattern_title = "<[Tt][Ii][Tt][Ll][Ee]>(.*)<"
local pattern_aframe = "<a%-scene"
app.on('scan_experience', function(exp)
--print_r(exp)
end)
app.on('dir', function(opts)
@ -37,7 +36,7 @@ app.on('scan_experience_file', function(exp)
end
end
if size < 100000 then -- skip large binary files > 100kb
if me.isWrapFile(exp.path) and size < 100000 then -- skip large binary files > 100kb
local data = util.readfile( exp.file.fullpath)
if data then
if data:match(pattern_fireboxroom) or
@ -50,7 +49,7 @@ app.on('scan_experience_file', function(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 = {}
exp.janusxr = exp.janusxr or {}
print("✅ └─ plugin/janusxr: " .. exp.file.name)
if data:match(pattern_aframe) and app.opts.plugin_janusxr_wrap_aframe == 'enabled' then
exp.janusxr.wrap = {aframe = true }
@ -89,6 +88,13 @@ local plugin = {
default="https://p.janusxr.org https://cors.xrforge.org",
values=''
},
{
key='app.opts.plugin_janusxr_wrap_custom',
title='VR wrap custom',
info='include "index.jml" files (if found) in generated JML',
default="index.jml",
values={ ["index.jml"] = "index.jml"}
},
{
key='app.opts.plugin_janusxr_wrap_3dfile',
title='VR wrap 3D file',
@ -172,6 +178,11 @@ local plugin = {
}
},
isWrapFile = function(path)
return tostring(path):match("/" .. app.opts.plugin_janusxr_wrap_custom:gsub("%.",".") .. "jml$")
and true or false
end,
wrapRoomAroundFile = function(item)
local room = ''
if item.janusxr.wrap.object then

123
src/plugin/openbrush.lua Normal file
View file

@ -0,0 +1,123 @@
local util = require('util')
app.on('init', function()
end)
app.on('scan_experience', function(exp)
end)
app.on('scan_experience_file', function(exp)
end)
app.on('set', function(k,v)
end)
app.on('scheduler', function(opts)
-- if opts.interval == app.opts.plugin_archive_when then
--
-- end
end)
local sync_URL = app.opts_plugin_openbrush_sync_URL or ''
-- this registers the plugin UI
local plugin = {
name = "OpenBrush",
infowide = true,
info = [[
<img src="img/openbrush.png" style="width:50%; max-width:233px; display:inline-block; float:left; margin-right:20px;"/>
<a href="https://openbrush.app/" target="_blank">OpenBrush</a> lets you paint in 3D space with virtual reality.<br>
XRForge's webviewer (<a href="https://github.com/jbaicoianu/janusweb">JanusWeb</a>) supports interconnecting OpenBrush projects via 3D portals.<br/>
OpenBrush projects are stored in a (selfhosted) <a href="https://icosa.gallery" target="_blank">icosa.gallery</a> instance, which can be configured below.
]],
opts = {
{
key='app.opts.plugin_openbrush_sync_when',
title='When to sync',
info='when to check for new experiences?',
default = "hourly",
values={disabled="disabled", daily="daily", hourly="hourly"}
},
{
key='app.opts.plugin_openbrush_sync_folder_thumbnail',
title='Sync to folder',
info='openbrush (icosa.gallery) assets will be saved here',
placeholder = "openbrush",
default = "openbrush",
values=''
},
{
key='app.opts.plugin_openbrush_sync_folder',
title='Thumbnail',
info='URL of Thumbnail for folder/portal',
placeholder = "img/openbrush.png",
default = "img/openbrush.png",
values=''
},
{
key='app.opts.plugin_openbrush_sync_URL',
title='Icosa gallery URL',
info='public/selfhosted <a href="https://github.com/icosa-foundation/icosa-gallery target="_blank">icosa.gallery</a> server-instance',
placeholder = "https://icosa.gallery",
default = "https://icosa.gallery",
values=''
},
{
key='app.opts.plugin_openbrush_sync_category',
title='category',
info=( sync_URL and 'space-separated, leave empty or see <a href="https://api.' .. sync_URL .. '/v1/docs#/Assets/icosa_api_assets_get_assets">API docs</a>' or ''),
placeholder = "ART",
default = "",
values=''
},
{
key='app.opts.plugin_openbrush_sync_keywords',
title='keywords',
info=( sync_URL and 'space-separated, leave empty or see <a href="https://api.' .. sync_URL .. '/v1/docs#/Assets/icosa_api_assets_get_assets">API docs</a>' or ''),
placeholder = "xrforge",
default = "",
values=''
},
{
key='app.opts.plugin_openbrush_sync_tag',
title='tags',
info=( sync_URL and 'space-separated, leave empty or see <a href="https://api.' .. sync_URL .. '/v1/docs#/Assets/icosa_api_assets_get_assets">API docs</a>' or ''),
placeholder = "xrforge",
default = "",
values=''
},
{
key='app.opts.plugin_openbrush_sync_triangle_max',
title='Polygons maximum',
info=( sync_URL and 'performance-cap, leave empty or see <a href="https://api.' .. sync_URL .. '/v1/docs#/Assets/icosa_api_assets_get_assets">API docs</a>' or ''),
placeholder = "10000",
default = "",
values=''
},
{
key='app.opts.plugin_openbrush_sync_author',
title='Author name',
info='filter assets on specific Author name',
placeholder='sarah',
default = "",
values=""
},
{
key='app.opts.plugin_openbrush_sync_authorid',
title='Author id',
info='filter assets on specific Author id',
placeholder='9e8b98fbe',
default = "",
values=""
},
{
key='app.opts.plugin_openbrush_sync_collection',
title='Collection required',
info='should assets be part of a collection?',
default = "enabled",
values={enabled="enabled", disabled="disabled"}
}
}
}
return plugin