🔧 master: work in progress [might break]
This commit is contained in:
parent
9dd86155c6
commit
21152b128c
21 changed files with 363 additions and 66 deletions
3
.env
3
.env
|
|
@ -1,7 +1,8 @@
|
||||||
# aliases
|
# aliases
|
||||||
build(){ $(pwd)/util/xrforge.sh build; }
|
build(){ $(pwd)/util/xrforge.sh build; }
|
||||||
|
rebuild(){ $(pwd)/util/xrforge.sh rebuild; }
|
||||||
|
|
||||||
# server hook
|
# forgejo server hook
|
||||||
#test "$GITEA_ROOT_URL" = "https://xrforge.isvery.ninja/" && {
|
#test "$GITEA_ROOT_URL" = "https://xrforge.isvery.ninja/" && {
|
||||||
# cp -r example/assets/* .
|
# cp -r example/assets/* .
|
||||||
#}
|
#}
|
||||||
|
|
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -1,2 +1,5 @@
|
||||||
experiences
|
experienceA
|
||||||
|
experienceB
|
||||||
result
|
result
|
||||||
|
src/v
|
||||||
|
janusweb*
|
||||||
|
|
|
||||||
22
README.md
22
README.md
|
|
@ -1,10 +1,3 @@
|
||||||
|
|
||||||
```
|
|
||||||
$ source .env # not needed if your system has autoenv
|
|
||||||
$ util/xrforge.sh build # fast: repeatable build
|
|
||||||
$ nix-build # slow: reproducable nix build (for experts)
|
|
||||||
```
|
|
||||||
|
|
||||||
NOTES:
|
NOTES:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -44,6 +37,21 @@ curl -L -X 'GET' 'http://xrforge.isvery.ninja/models?page=1&order=name' -H
|
||||||
curl -L -X 'GET' 'http://xrforge.isvery.ninja/models?page=1&order=recent' -H 'accept: application/vnd.manyfold.v0+json'
|
curl -L -X 'GET' 'http://xrforge.isvery.ninja/models?page=1&order=recent' -H 'accept: application/vnd.manyfold.v0+json'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Developing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ source .env # not needed if your system has autoenv
|
||||||
|
$ build # fast: repeatable build
|
||||||
|
$ rebuild # faster: lua-repeatable build
|
||||||
|
$ nix-build # slow: reproducable nix build (for experts)
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run with debug flag to see output of `trace()` calls
|
||||||
|
```bash
|
||||||
|
$ DEBUG=1 result/bin/xrforge.com
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Permacomputing Spirit
|
## Permacomputing Spirit
|
||||||
|
|
||||||
* developed on [Dillo](https://dillo-browser.github.io/) as lowest common denominator / compatibility
|
* developed on [Dillo](https://dillo-browser.github.io/) as lowest common denominator / compatibility
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
-H
|
-H
|
||||||
"Access-Control-Allow-Origin: *"
|
Access-Control-Allow-Origin: *
|
||||||
-H
|
-H
|
||||||
"Access-Control-Allow-Method: GET, POST, OPTIONS"
|
Access-Control-Allow-Method: GET, POST, OPTIONS
|
||||||
-H
|
-H
|
||||||
"Allow: GET, POST, OPTIONS"
|
Allow: GET, POST, OPTIONS
|
||||||
-D
|
-D
|
||||||
.
|
.
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package.path = package.path .. ";.lua/?.lua"
|
||||||
package.path = package.path .. ";src/.lua/?.lua"
|
package.path = package.path .. ";src/.lua/?.lua"
|
||||||
package.path = package.path .. ";middleware/?.lua"
|
package.path = package.path .. ";middleware/?.lua"
|
||||||
package.path = package.path .. ";cmd/?.lua"
|
package.path = package.path .. ";cmd/?.lua"
|
||||||
|
package.path = package.path .. ";plugin/?.lua"
|
||||||
|
|
||||||
print = function(...) Log(kLogInfo, ... or "''") end -- nice redbean logging from now on
|
print = function(...) Log(kLogInfo, ... or "''") end -- nice redbean logging from now on
|
||||||
|
|
||||||
|
|
@ -12,27 +13,30 @@ json = require "json"
|
||||||
HidePath('/usr/share/zoneinfo/')
|
HidePath('/usr/share/zoneinfo/')
|
||||||
HidePath('/usr/share/ssl/')
|
HidePath('/usr/share/ssl/')
|
||||||
|
|
||||||
dir = require "opendirectory"
|
|
||||||
|
|
||||||
-- create
|
-- create
|
||||||
app = require("soakbean") {
|
app = require("soakbean") {
|
||||||
bin = "./xrforge.com",
|
bin = "./xrforge.com",
|
||||||
bindir = arg[-1]:gsub("xrforge.com",""),
|
bindir = arg[-1]:gsub("xrforge.com",""),
|
||||||
cache = {},
|
cache = { items = {} },
|
||||||
|
plugin = {},
|
||||||
opts = {},
|
opts = {},
|
||||||
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"},
|
||||||
|
createplugin = {file="cmd/createplugin.lua", info="generates skeleton plugin"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
-- 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
|
||||||
app.init = function() end
|
app.init = function() end
|
||||||
|
app.scan = require('scan').scan
|
||||||
|
|
||||||
-- load config
|
-- load config
|
||||||
app.opts = require('config')(app)
|
app.opts = require('config')(app)
|
||||||
|
|
||||||
|
-- load plugins
|
||||||
|
app.plugin.janusxr = require('plugin/janusxr')
|
||||||
|
|
||||||
app.runcmd(app) -- run clicmds
|
app.runcmd(app) -- run clicmds
|
||||||
|
|
||||||
|
|
@ -62,16 +66,17 @@ app --
|
||||||
.use( app.response() ) -- try serve app response (if any)
|
.use( app.response() ) -- try serve app response (if any)
|
||||||
.use( function(req,next) Route() end) -- fallback default redbean fileserver
|
.use( function(req,next) Route() end) -- fallback default redbean fileserver
|
||||||
|
|
||||||
function OnHttpRequest() app.run() end
|
|
||||||
|
|
||||||
app.on('init', function()
|
app.on('init', function()
|
||||||
if assert(unix.fork()) == 0 then
|
if assert(unix.fork()) == 0 then
|
||||||
os.execute("ls ; sleep 5")
|
--os.execute("ls ; sleep 5")
|
||||||
|
app.scan()
|
||||||
print("ok")
|
print("ok")
|
||||||
--local ok, headers, body = Fetch('http://127.0.0.1:8080/test')
|
--local ok, headers, body = Fetch('http://127.0.0.1:8080/test')
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
function OnHttpRequest() app.run() end
|
||||||
|
|
||||||
OnServerStart = function()
|
OnServerStart = function()
|
||||||
app.init() -- this triggers init event
|
app.init() -- this triggers init event
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,23 @@ return function(app)
|
||||||
if k == 'app.opts' then
|
if k == 'app.opts' then
|
||||||
app.opts = v
|
app.opts = v
|
||||||
app.opts.updated = os.time()
|
app.opts.updated = os.time()
|
||||||
local newconfig = "app.on('init', function()\n\tprint('config loaded')\nend)\n\nreturn " .. util.dump(app.opts)
|
local newconfig = [[
|
||||||
|
|
||||||
|
-- TIP: run 'xrforge.com createplugin' to start writing plugins
|
||||||
|
|
||||||
|
app.on('init', function()
|
||||||
|
print('config loaded')
|
||||||
|
|
||||||
|
local scan = app.scan
|
||||||
|
app.scan = function()
|
||||||
|
os.execute("echo scan before-hook")
|
||||||
|
scan()
|
||||||
|
os.execute("echo scan after-hook")
|
||||||
|
end
|
||||||
|
|
||||||
|
end)
|
||||||
|
|
||||||
|
]] .. "\n\nreturn " .. util.dump(app.opts)
|
||||||
newconfig = newconfig:gsub("^}$"," init = function() print('xrforge.lua config loaded') end\n}")
|
newconfig = newconfig:gsub("^}$"," init = function() print('xrforge.lua config loaded') end\n}")
|
||||||
util.writefile( app.bindir .. configfile, newconfig )
|
util.writefile( app.bindir .. configfile, newconfig )
|
||||||
print("stored xrforge.lua")
|
print("stored xrforge.lua")
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,10 @@ dir.foreach = function(path,cb)
|
||||||
if name == "." then goto continue end
|
if name == "." then goto continue end
|
||||||
attr,err = unix.stat(path..'/'..name, unix.AT_SYMLINK_NOFOLLOW)
|
attr,err = unix.stat(path..'/'..name, unix.AT_SYMLINK_NOFOLLOW)
|
||||||
if err then print("error: ".. name .. ": " ..err) end
|
if err then print("error: ".. name .. ": " ..err) end
|
||||||
cb(path,stat,state,name,kind,ino,off,attr)
|
cb(path,stat,state,name,kind,ino,off,attr, path .. "/" ..name)
|
||||||
::continue::
|
::continue::
|
||||||
end
|
end
|
||||||
|
return state
|
||||||
end
|
end
|
||||||
|
|
||||||
dir.serve = function(folder) -- raw redbean function (use dir.foreach in soakbean)
|
dir.serve = function(folder) -- raw redbean function (use dir.foreach in soakbean)
|
||||||
|
|
@ -97,7 +98,7 @@ dir.serve = function(folder) -- raw redbean function (use dir.foreach in soakbea
|
||||||
Write('<tbody>\r\n')
|
Write('<tbody>\r\n')
|
||||||
|
|
||||||
local stat, state = dir.scan(path)
|
local stat, state = dir.scan(path)
|
||||||
dir.foreach(path, function(path,stat,state,name,kind,ino,off,attr)
|
dir.foreach(path, function(path,stat,state,name,kind,ino,off,attr,fullpath)
|
||||||
Write('<tr>\r\n')
|
Write('<tr>\r\n')
|
||||||
Write('<td>')
|
Write('<td>')
|
||||||
local link = EscapeHtml(name)
|
local link = EscapeHtml(name)
|
||||||
|
|
|
||||||
1
src/.lua/plugin
Symbolic link
1
src/.lua/plugin
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../plugin
|
||||||
50
src/.lua/scan.lua
Normal file
50
src/.lua/scan.lua
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
local dir = require "opendirectory"
|
||||||
|
|
||||||
|
local scan
|
||||||
|
scan = {
|
||||||
|
|
||||||
|
shouldHideFile = function(name)
|
||||||
|
return name == ".."
|
||||||
|
or name == "util" -- repository
|
||||||
|
or name == ".git" -- files
|
||||||
|
or name == "src" --
|
||||||
|
or name == "result" --
|
||||||
|
end,
|
||||||
|
|
||||||
|
scan = function()
|
||||||
|
-- scan dirs
|
||||||
|
local dref = dir.foreach( app.opts.disk_dir, function(path,stat,state,name,kind,ino,off,attr,fullpath)
|
||||||
|
if kind == unix.DT_DIR and not scan.shouldHideFile(name) then
|
||||||
|
local experience = {
|
||||||
|
path = fullpath,
|
||||||
|
name = name,
|
||||||
|
tag = {},
|
||||||
|
file = {stat=stat,state=state,kind=kind,ino=ino,off=off,attr=attr,fullpath=fullpath,name=name,path=path}
|
||||||
|
}
|
||||||
|
app.pub("scan_experience", nil, experience)
|
||||||
|
print("ℹ️ ".. fullpath)
|
||||||
|
|
||||||
|
-- scan files
|
||||||
|
local fref = dir.foreach(fullpath, function(path,stat,state,name,kind,ino,off,attr, fullpath)
|
||||||
|
if kind ~= unix.DT_DIR and not scan.shouldHideFile(name) then
|
||||||
|
experience.file = {stat=stat,state=state,kind=kind,ino=ino,off=off,attr=attr,fullpath=fullpath,name=name,path=path}
|
||||||
|
app.pub("scan_experience_file", nil, experience)
|
||||||
|
local size = attr:size()
|
||||||
|
trace("ℹ️ ".. fullpath)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
fref:close()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
dref:close()
|
||||||
|
|
||||||
|
foreach( app.cache.items, function(k,v)
|
||||||
|
-- remove file attributes (which are closed already)
|
||||||
|
v.file.stat = nil
|
||||||
|
v.file.attr = nil
|
||||||
|
v.file.state = nil
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
return scan
|
||||||
|
|
@ -197,9 +197,9 @@ sb = {
|
||||||
for k,v in pairs(argv) do
|
for k,v in pairs(argv) do
|
||||||
app.opts[ v:gsub("=.*","") ] = v:gsub(".*=","")
|
app.opts[ v:gsub("=.*","") ] = v:gsub(".*=","")
|
||||||
end
|
end
|
||||||
for k,v in pairs(app.opts) do
|
for k,v in pairs(argv) do
|
||||||
if app.cmd[k] then
|
if app.cmd[v] then
|
||||||
local file = app.cmd[k].file
|
local file = app.cmd[v].file
|
||||||
return require( file:sub(0,-5) )(app,argv)
|
return require( file:sub(0,-5) )(app,argv)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,16 @@ util.template = function(content,data)
|
||||||
return app.tpl( content, mdata )
|
return app.tpl( content, mdata )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
util.contains = function(tab,k_or_v)
|
||||||
|
local result = false
|
||||||
|
foreach( tab, function(k,v)
|
||||||
|
if k == k_or_v or v == k_or_v then
|
||||||
|
result = true
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
util.memoize = function(fn, ttl_seconds)
|
util.memoize = function(fn, ttl_seconds)
|
||||||
local cached_results = nil
|
local cached_results = nil
|
||||||
local last_executed = 0
|
local last_executed = 0
|
||||||
|
|
|
||||||
48
src/cmd/createplugin.lua
Normal file
48
src/cmd/createplugin.lua
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
return function(app,argv)
|
||||||
|
print( [[
|
||||||
|
|
||||||
|
--
|
||||||
|
-- 1. put the code below in a file ('xrforge.myplugin.lua' e.g.)
|
||||||
|
-- 2. make sure to require it at the top of xrforge.lua (require('xrforge.myplugin') e.g.)
|
||||||
|
-- 3. profit!
|
||||||
|
--
|
||||||
|
|
||||||
|
app.on('scan_experience', function(exp)
|
||||||
|
print_r(exp)
|
||||||
|
end)
|
||||||
|
|
||||||
|
app.on('scan_experience_file', function(exp)
|
||||||
|
print_r(exp)
|
||||||
|
end)
|
||||||
|
|
||||||
|
app.on('set', function(k,v)
|
||||||
|
print("content was updated")
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- plugin UI
|
||||||
|
local plugin = {
|
||||||
|
name = "MyPlugin",
|
||||||
|
info = "description / usage of your plugin goes here (html supported)",
|
||||||
|
opts = {
|
||||||
|
{
|
||||||
|
key='app.opts.plugin_myplugin_foo',
|
||||||
|
title='foo title',
|
||||||
|
info='Enable or disable foo',
|
||||||
|
default="yes",
|
||||||
|
values={yes="yes",no="no",maybe="maaaaybe"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key='app.opts.plugin_myplugin_bar',
|
||||||
|
title='foo title',
|
||||||
|
info='Name your bar',
|
||||||
|
default="bar",
|
||||||
|
values=""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugin
|
||||||
|
|
||||||
|
]] )
|
||||||
|
os.exit()
|
||||||
|
end
|
||||||
|
|
@ -235,6 +235,15 @@ img.icon{ display:none; }
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b.tag{
|
||||||
|
display:inline-block;
|
||||||
|
background: #77f;
|
||||||
|
color: white;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 1px 4px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
/* progressive enhancement quirks */
|
/* progressive enhancement quirks */
|
||||||
|
|
||||||
.spectrum{ display:none }
|
.spectrum{ display:none }
|
||||||
|
|
|
||||||
|
|
@ -39,11 +39,12 @@ body{
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid .tile .text{
|
.grid .tile .text{
|
||||||
padding: 10px 20px 10px 20px !important;
|
padding: 10px 20px 10px 15px !important;
|
||||||
|
font-size:14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid .tile img.icon{
|
.grid .tile img.icon{
|
||||||
transform: translate(0,5px);
|
transform: translate(0,-3px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.clear{
|
.clear{
|
||||||
|
|
@ -69,11 +70,11 @@ img.icon{
|
||||||
iframe#viewer{
|
iframe#viewer{
|
||||||
position: fixed;
|
position: fixed;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc( 100vh - 59px);
|
height: calc( 99.7vh - 59px);
|
||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
background: #FFF;
|
background: #FFF;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 70px;
|
top: 62px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* telescopic text */
|
/* telescopic text */
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ ${notification}
|
||||||
Keywords
|
Keywords
|
||||||
</td>
|
</td>
|
||||||
<td >
|
<td >
|
||||||
<input type="text" value="${opts.hide_keywords}"></input>
|
<input type="text" name="opts.hide_keywords" value="${opts.hide_keywords}"></input>
|
||||||
</td>
|
</td>
|
||||||
<td class="col3">
|
<td class="col3">
|
||||||
Space-separated, <a href="http://lua-users.org/wiki/PatternsTutorial" target="_blank">lua patterns</a> are allowed
|
Space-separated, <a href="http://lua-users.org/wiki/PatternsTutorial" target="_blank">lua patterns</a> are allowed
|
||||||
|
|
@ -145,13 +145,17 @@ ${notification}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<div style="margin-left:165px">
|
</div>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
<br/>
|
||||||
|
${plugins}
|
||||||
|
|
||||||
|
<div style="margin-left:187px">
|
||||||
<div class="btn">
|
<div class="btn">
|
||||||
<input type="submit" class="btn secondary" value="Save" style=""/>
|
<input type="submit" class="btn secondary" value="Save" style=""/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
${footer}
|
${footer}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,57 @@
|
||||||
local util = require("util")
|
local util = require("util")
|
||||||
|
|
||||||
local data = util.merge({notification=''},{ opts = app.opts })
|
local data = util.merge({notification=''},{ opts = app.opts })
|
||||||
|
data.plugins = ""
|
||||||
|
|
||||||
|
function pluginInput(opt)
|
||||||
|
local html = ""
|
||||||
|
html = html .. [[
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
]]
|
||||||
|
html = html .. opt.title
|
||||||
|
html = html .. [[
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
]]
|
||||||
|
if type(opt.values) == 'table' then
|
||||||
|
html = html .. util.template('<select name="${key}" value="${value}">\n', {
|
||||||
|
key = opt.key,
|
||||||
|
value = app.opts[key]
|
||||||
|
})
|
||||||
|
foreach( opt.values, function(k,v)
|
||||||
|
html = html .. util.template('<option value="${v}">${k}</option>\n',{
|
||||||
|
k=k,
|
||||||
|
v=v
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
html = html .. "</select>\n"
|
||||||
|
else
|
||||||
|
html = html .. util.template('<input type="text" name="${key}" value="${value}"></input>',{
|
||||||
|
key = opt.key,
|
||||||
|
value = app.opts[key]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
html = html .. util.template([[
|
||||||
|
</td>
|
||||||
|
<td class="col3">${info}</td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
]],opt)
|
||||||
|
return html
|
||||||
|
end
|
||||||
|
|
||||||
|
function pluginUI(name,plugin)
|
||||||
|
local plugindata = util.flatten(plugin,"plugin")
|
||||||
|
plugindata.opts = ""
|
||||||
|
foreach(plugin.opts, function(k,opt)
|
||||||
|
plugindata.opts = plugindata.opts .. pluginInput(opt)
|
||||||
|
end)
|
||||||
|
print_r(plugindata)
|
||||||
|
data.plugins = data.plugins .. util.template( LoadAsset('/page/admin/plugin.html'), plugindata)
|
||||||
|
end
|
||||||
|
|
||||||
|
function saveData()
|
||||||
if GetMethod() == 'POST' then
|
if GetMethod() == 'POST' then
|
||||||
local params = GetParams()
|
local params = GetParams()
|
||||||
local saveconfig = false
|
local saveconfig = false
|
||||||
|
|
@ -18,7 +68,10 @@ if GetMethod() == 'POST' then
|
||||||
data.notification = '<div class="notification">no changes detected</div>'
|
data.notification = '<div class="notification">no changes detected</div>'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
foreach( app.plugin, pluginUI )
|
||||||
|
saveData()
|
||||||
local html = util.template( LoadAsset("page/admin/index.html"),data)
|
local html = util.template( LoadAsset("page/admin/index.html"),data)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
21
src/page/admin/plugin.html
Normal file
21
src/page/admin/plugin.html
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
<div class="tab">
|
||||||
|
<div class="label col2">${plugin.name} <b class="tag">plugin</b></div>
|
||||||
|
</div>
|
||||||
|
<div class="margin1">
|
||||||
|
<table width="100%">
|
||||||
|
<tr>
|
||||||
|
<th width="165"/>
|
||||||
|
<th />
|
||||||
|
<th />
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td>${plugin.info}<br/><br/></td>
|
||||||
|
</tr>
|
||||||
|
${opts}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
|
@ -6,21 +6,6 @@ ${header}
|
||||||
</div>
|
</div>
|
||||||
<hr style="margin-top:0">
|
<hr style="margin-top:0">
|
||||||
|
|
||||||
<div class="btn">
|
|
||||||
<a href="#foo">button</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="btn">
|
|
||||||
<a href="#foo" class="primary">button primary <img src="img/arrow-down.svg" class="icon"/></a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="btn">
|
|
||||||
<a href="https://foo.com" target="_blank" class="secondary">button secondary <img src="img/arrow-right.svg" class="icon"/></a>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<hr>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div class="tile">
|
<div class="tile">
|
||||||
<div class="img" style="background-image:url(https://xrforge.isvery.ninja/models/dpjnj8pt1cjc/model_files/bzjvdm7l523l.png?derivative=preview);"></div>
|
<div class="img" style="background-image:url(https://xrforge.isvery.ninja/models/dpjnj8pt1cjc/model_files/bzjvdm7l523l.png?derivative=preview);"></div>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
${header}
|
${header}
|
||||||
|
|
||||||
<iframe border="0" frameborder="0" src="https://web.janusxr.org" id="viewer"/>
|
<iframe border="0" frameborder="0" src="/v/index.html#janus.url=/" id="viewer"/>
|
||||||
|
|
||||||
${footer}
|
${footer}
|
||||||
|
|
|
||||||
67
src/plugin/janusxr.lua
Normal file
67
src/plugin/janusxr.lua
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
local util = require('util')
|
||||||
|
|
||||||
|
local pattern_fireboxroom = "[Ff][Ii][Rr][Ee][Bb][Oo][Xx][Rr][Oo][Oo][Mm][ ]?.*>"
|
||||||
|
local pattern_title = "<[Tt][Ii][Tt][Ll][Ee]>(.*)<"
|
||||||
|
|
||||||
|
app.on('scan_experience', function(exp)
|
||||||
|
--print_r(exp)
|
||||||
|
end)
|
||||||
|
|
||||||
|
app.on('scan_experience_file', function(exp)
|
||||||
|
local size = exp.file.attr:size()
|
||||||
|
if exp.file.name:match(".glb") and not util.contains(exp.tag,"xrfragment") then
|
||||||
|
print("✅ └─ plugin/janusxr: generating janusxr.xml")
|
||||||
|
elseif size < 1000 then -- skip large binary files
|
||||||
|
local data = util.readfile( exp.file.fullpath)
|
||||||
|
if data:match(pattern_fireboxroom) then
|
||||||
|
table.insert(exp.tag, "janusxr")
|
||||||
|
local title = data:match(pattern_title)
|
||||||
|
if title then exp.title = title:gsub("<.*","") end
|
||||||
|
app.pub("scan_experience_janusxr", nil, {exp=exp, item=item}) -- be nice to other plugins
|
||||||
|
table.insert( app.cache.items, exp)
|
||||||
|
print("✅ └─ plugin/janusxr: " .. exp.file.name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
app.on('set', function(k,v)
|
||||||
|
print("content was updated")
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- this registers the plugin UI
|
||||||
|
local plugin = {
|
||||||
|
name = "JanusXR",
|
||||||
|
info = '<a href="https://coderofsalvation.github.io/janus-guide" target="_blank">janusxr</a> allows composing (interconnected) 3D experiences (via portals) via its JML markup language. It also supports AFRAME (geometry)markup.',
|
||||||
|
opts = {
|
||||||
|
{
|
||||||
|
key='app.opts.plugin_janusxr_wrap_image',
|
||||||
|
title='wrap images',
|
||||||
|
info='Generate <a href="https://coderofsalvation.github.io/janus-guide/#/build/room" target="_blank">janusxr.xml</a> to embed images into an XR experience',
|
||||||
|
default="yes",
|
||||||
|
values={yes="yes",no="no"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key='app.opts.plugin_janusxr_wrap_video',
|
||||||
|
title='wrap videos',
|
||||||
|
info='Generate <a href="https://coderofsalvation.github.io/janus-guide/#/build/room" target="_blank">janusxr.xml</a> to embed videos into an XR experience',
|
||||||
|
default="yes",
|
||||||
|
values={yes="yes",no="no"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key='app.opts.plugin_janusxr_wrap_aframe',
|
||||||
|
title='wrap AFRAME',
|
||||||
|
info='Generate <a href="https://coderofsalvation.github.io/janus-guide/#/build/room" target="_blank">janusxr.xml</a> to embed AFRAME markup into an XR experience',
|
||||||
|
default="yes",
|
||||||
|
values={yes="yes",no="no"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key='app.opts.plugin_janusxr_wrap_template',
|
||||||
|
title='template',
|
||||||
|
info='What kind of space should images/videos be rendered into?',
|
||||||
|
default="random",
|
||||||
|
values={random="random room",plane="wirefloor",room1="room1",room2="room2",room3="room3",room4="room4",room5="room5",room6="room6",room7="room7"}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugin
|
||||||
|
|
@ -19,6 +19,15 @@ download(){
|
||||||
verify
|
verify
|
||||||
}
|
}
|
||||||
|
|
||||||
|
janusweb(){
|
||||||
|
version=1.7.4
|
||||||
|
test -f janusweb-${version}.tar.gz || {
|
||||||
|
wget "https://github.com/jbaicoianu/janusweb/releases/download/v${version}/janusweb-${version}.tar.gz"
|
||||||
|
tar -xvf janusweb-${version}.tar.gz
|
||||||
|
mv janusweb-${version} src/v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
"$@"
|
"$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,4 +37,9 @@ build(){
|
||||||
zip -r ../result/bin/xrforge.com * .lua .init.lua .args
|
zip -r ../result/bin/xrforge.com * .lua .init.lua .args
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rebuild(){
|
||||||
|
cd src
|
||||||
|
zip -r ../result/bin/xrforge.com .lua page plugin cmd css .init.lua .args
|
||||||
|
}
|
||||||
|
|
||||||
"$@"
|
"$@"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue