optimized scanner

This commit is contained in:
Leon van Kammen 2026-08-02 14:00:56 +02:00
parent 75c69332e1
commit e34a87d475
11 changed files with 73 additions and 32 deletions

2
run.sh
View file

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

View file

@ -21,7 +21,7 @@ app = require("soakbean") {
forkpids = {}, forkpids = {},
cmd={ cmd={
help = {file="cmd/help.lua", info="display all possible flags"}, help = {file="cmd/help.lua", info="display all possible flags"},
server = {file="cmd/server.lua", info="starts the webserver"}, server = {file="cmd/server.lua", info="starts the webserver [without --nobrowser]"},
admin = {file="cmd/server.lua", info="launch adminpanel to configure stuff (/admin)"}, admin = {file="cmd/server.lua", info="launch adminpanel to configure stuff (/admin)"},
createplugin = {file="cmd/createplugin.lua", info="generates skeleton plugin"}, createplugin = {file="cmd/createplugin.lua", info="generates skeleton plugin"},
generate = {file="cmd/generate.lua", info="generate www-folder with XR experiences"}, generate = {file="cmd/generate.lua", info="generate www-folder with XR experiences"},

View file

@ -1,8 +1,12 @@
local util = require('util')
return function(app,argv) return function(app,argv)
print("starting server") print("starting server")
if arg[1] == 'admin' then if not util.contains(arg,"--nobrowser") then
LaunchBrowser('/admin') if arg[1] == 'admin' then
else LaunchBrowser('/admin')
LaunchBrowser('/') else
LaunchBrowser('/')
end
end end
end end

View file

@ -155,6 +155,7 @@ form > table > tbody > tr > td:nth-child(3) {
background:#224; background:#224;
} }
pre{ pre{
line-height:initial !important;
font-family: monospace; font-family: monospace;
line-height: 1; line-height: 1;
word-spacing: normal; word-spacing: normal;

View file

@ -262,7 +262,7 @@ div.tab-frame > input#info:checked ~ .info{
left:5%; left:5%;
right:5%; right:5%;
max-height:60vh; max-height:60vh;
padding:0px 30px 30px 30px; padding:30px 30px 30px 30px;
background:#112e; background:#112e;
z-index:1000; z-index:1000;
overflow:hidden; overflow:hidden;

View file

@ -92,16 +92,48 @@ div#xrecosystem{
</header> </header>
<h3>What is it</h3> <h3>What is it</h3>
An open, seamless XR web built from simple URLs and directories, without gatekeepers.<br>
XRForge is a little VR/AR utility, which projects directories from (remote) filesystems into 3D, allowing users to 'surf' the deep immersive web, of experiences (3d files) and portal-rooms (directories). XRForge transforms standard local or remote file directories into interconnected 3D spaces. Users can seamlessly "surf" the spatial web, turning everyday directories into gateways and portals.
<br>
<br> <br>
<br> <div class="margin1">
<pre class="secondary">
┌───────────────────────────────────┐ ┌──────────────────────────────────────────┐
│ local disk │ │ Surf via 3D portals │
├───────────────────────────────────┤ └──────────────────────────────────────────┘
│ │
│ /myverse │ https://my.org/myverse
│ /elearnings │ https://my.org/myverse/elearnings
│ /elearning1/1.glb │ https://my.org/myverse/elearning/elearning1
│ /elearning2/2.glb │ https://my.org/myverse/elearning/elearning2
│ │
│ ┌──────────────────────────────┐ │
│ │ github / webdav / dropbox etc│ │
│ │ │ │
│ │ /mygames │ │ https://my.org/myverse/mygames
│ │ /biggusgateWebXR │ │ https://my.org/myverse/mygames/biggusgate
│ │ /spasca │ │ https://my.org/myverse/mygames/spasca
│ │ /otherxrforge │ │ https://my.org/myverse/otherxrforge
│ │ │ │
│ │ ┌───────────┐ ┌───────────┐ │ │
│ │ │/manyfold │ │archive.org│ │ │ https://my.org/myverse/manyfold
│ │ └───────────┘ └───────────┘ │ │ https://my.org/myverse/myarchive
│ │ │ │
│ │ +40 integrations! │ │
│ └──────────────────────────────┘ │
└───────────────────────────────────┘
</pre>
</div>
<h3>Why people want XRForge</h3> <h3>Why people want XRForge</h3>
<div> <div>
In short: a hyperscalable portal-system and <b>projection</b> of existing 2D ecosystems <b>into XR.</b><br> In short: hyperscalability (it uses web URLs) PLUS <b>portal-system</b> and <b>projection</b> of existing 2D ecosystems <b>into XR.</b><br>
XRForge interconnects experiences via portals, according to the <a href="https://coderofsalvation.github.io/janus-guide/" target="_blank">JanusXR</a> and <a href="https://xrfragment.org" target="_blank">XR Fragments standard</a>.<br> XRForge interconnects XR experiences via portals, thanks to <a href="https://coderofsalvation.github.io/janus-guide/" target="_blank">JanusXR</a> and <a href="https://xrfragment.org" target="_blank">XR Fragments standards</a>.<br>
The metaverse has shown: people <b>like 3D</b> but certain <b>existing</b> 2D ecosystems are king.<br> The metaverse has shown: people <b>like 3D</b> but certain <b>existing</b> 2D ecosystems are king.<br>
They're just more cost-efficient to use.<br> They're just more cost-efficient to use.<br>
Hence, XRForge incorporates the opensource <a href="https://coderofsalvation.github.io/janus-guide/" target="_blank">JanusXR</a>-client called <a href="https://github.com/jbaicoianu/janusweb" target="_blank">JanusWeb</a>, which promotes <b>projecting these ecosystems</b> as virtual <b>hyperlinked</b> worlds (via XR translators).<br> Hence, XRForge incorporates the opensource <a href="https://coderofsalvation.github.io/janus-guide/" target="_blank">JanusXR</a>-client called <a href="https://github.com/jbaicoianu/janusweb" target="_blank">JanusWeb</a>, which promotes <b>projecting these ecosystems</b> as virtual <b>hyperlinked</b> worlds (via XR translators).<br>

View file

@ -23,7 +23,7 @@ end}
local item = items[i] local item = items[i]
local icon = 'list-tree' local icon = 'list-tree'
local thumbnail = '' local thumbnail = ''
if #item.thumbnail > 0 then thumbnail = 'style="background-image: url(' .. item.thumbnail .. ');"' end if #item.thumbnail > 0 then thumbnail = 'style="background-image: url(' .. EscapeFragment(item.thumbnail) .. ');"' end
if item.view3D or item.portal3D == false then icon = 'play' end if item.view3D or item.portal3D == false then icon = 'play' end
print([[ print([[
<div class="tile"> <div class="tile">

View file

@ -38,7 +38,7 @@ return {
end end
-- add items from dir -- add items from dir
if match(v.parent.path, matchpath) then if match(v.parent.path, matchpath) and (v.dir or v.view3D) then
local parent = app.cache.items[ v.parent.id ] local parent = app.cache.items[ v.parent.id ]
res.items[ v.id ] = v res.items[ v.id ] = v
res.parent = parent res.parent = parent

View file

@ -35,7 +35,7 @@ return {
path = scandir, path = scandir,
url = "/" .. util.stripPath(scandir), url = "/" .. util.stripPath(scandir),
name = scandir:gsub(".*/",""), name = scandir:gsub(".*/",""),
title = scandir:gsub(".*/",""), title = scandir:gsub(".*/",""):gsub("-"," "),
file = { ino = scandir }, file = { ino = scandir },
id = scandir id = scandir
} }
@ -57,9 +57,11 @@ return {
-- cleanup file handles -- cleanup file handles
foreach( app.cache.items, function(k,v) foreach( app.cache.items, function(k,v)
-- remove file attributes (which are closed already) -- remove file attributes (which are closed already)
v.file.stat = nil if v.file then
v.file.attr = nil v.file.stat = nil
v.file.state = nil v.file.attr = nil
v.file.state = nil
end
end) end)
end, end,
@ -73,7 +75,7 @@ return {
path = fullpath, path = fullpath,
url = "/" .. util.stripPath(fullpath), url = "/" .. util.stripPath(fullpath),
name = name, name = name,
title = name, title = name:gsub("-"," "),
sidecarfile = {}, sidecarfile = {},
thumbnail = '', thumbnail = '',
tag = {}, tag = {},
@ -82,22 +84,14 @@ return {
} }
experience.parent = parent experience.parent = parent
-- check for thumbnail
local thumbExt = {"png","jpg","webp"}
foreach( thumbExt, function(k,ext)
local thumbnailFile = fullpath .. "/" .. name .. "." .. ext
if util.fileExist( thumbnailFile ) then
print("✅ └─ plugin/diskscan: detected .".. ext:lower() .. " thumbnail file")
experience.thumbnail = "/" .. util.stripPath(thumbnailFile)
end
end)
if seen[ino] then return end -- dont process dirs/files twice if seen[ino] then return end -- dont process dirs/files twice
if (kind == unix.DT_LNK) then if (kind == unix.DT_LNK) then
local stat, err = unix.stat(fullpath) local stat, err = unix.stat(fullpath)
experience.id_target = stat:ino() if stat then
seen.symlinks[ ino ] = experience experience.id_target = stat:ino()
seen.symlinks[ ino ] = experience
end
return return
end end
@ -110,6 +104,16 @@ return {
experience.portal3D = true -- can be viewed as 3d portal experience.portal3D = true -- can be viewed as 3d portal
app.pub("scan_experience", nil, experience) app.pub("scan_experience", nil, experience)
app.cache.items[ino] = experience app.cache.items[ino] = experience
-- check for directory thumbnail sidecarfile
local thumbExt = {"png","jpg","webp"}
foreach( thumbExt, function(k,ext)
local thumbnailFile = fullpath .. '.' .. ext
if util.fileExist( thumbnailFile ) then
experience.thumbnail = "/" .. util.stripPath(thumbnailFile)
print("✅ └─ plugin/diskscan: detected .".. ext:lower() .. " thumbnail file: " .. thumbnailFile)
end
end)
-- scan children
me.scanDir(fullpath,experience,seen,symlinks) me.scanDir(fullpath,experience,seen,symlinks)
end end

View file

@ -9,7 +9,7 @@ end)
app.on('scan_experience_file', function(exp) app.on('scan_experience_file', function(exp)
local size = exp.file.attr:size() local size = exp.file.attr:size()
if size < 1000 then -- skip large binary files if 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
if data:match(pattern_fireboxroom) then if data:match(pattern_fireboxroom) then

View file

@ -24,7 +24,7 @@ app.on('scan_experience_file', function(exp)
end) end)
-- set thumbnail if any -- set thumbnail if any
if exp.sidecarfile.png then if exp.sidecarfile.png then
exp.thumnbail = exp.sidecarfile.png exp.thumbnail = exp.sidecarfile.png
end end
local jsonfile = exp.path:gsub("."..ext.."$",".json") local jsonfile = exp.path:gsub("."..ext.."$",".json")
-- scan for hrefs in json sidecarfile -- scan for hrefs in json sidecarfile