diff --git a/README.md b/README.md index 58ff181..82d2c62 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,11 @@ manual scan (via cli?) curl -L -X 'GET' 'http://xrforge.isvery.ninja/models?page=1&order=name' -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' ``` + +## Permacomputing Spirit + +* developed on [Dillo](https://dillo-browser.github.io/) as lowest common denominator / compatibility +* does not use javascript unless really needed (WebXR being the exception) +* server is using lua-scripting via cosmopolitan libc's [redbean](https://redbean.dev) + +> So yes in case you'd think the codebase is 90-ish: that's **exactly why it works** on potato-devices AND modern devices. diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..73a5f05 --- /dev/null +++ b/run.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cd src +../result/bin/xrforge.com -D . -- server diff --git a/src/.init.lua b/src/.init.lua index bebd3a2..8ded0fa 100644 --- a/src/.init.lua +++ b/src/.init.lua @@ -3,6 +3,8 @@ package.path = package.path .. ";src/.lua/?.lua" package.path = package.path .. ";middleware/?.lua" package.path = package.path .. ";cmd/?.lua" +print = function(...) Log(kLogInfo, ... or "''") end -- nice redbean logging from now on + util = require "util" json = require "json" @@ -15,24 +17,32 @@ dir = require "opendirectory" -- create app = require("soakbean") { bin = "./xrforge.com", + bindir = arg[-1]:gsub("xrforge.com",""), cache = {}, - opts = { - title="My XRForge experiences", - subtitle="Portable XR experiences for PhoneVR, VRheadset, desktop & mobile." - }, + opts = {}, cmd={ - help = {file="help.lua", info="displays help cmds"}, - server = {file="server.lua", info="starts the webserver"} - }, - title = 'XRForge - local-first XR experiences', - subtitle = 'XRForge makes local-first XR easy', - notes = {'ðĪĐ portable selfsovereign', 'ð§ JanusXR / XR Fragments', 'âŧ decentralized'} + help = {file="cmd/help.lua", info="display all possible flags"}, + server = {file="cmd/server.lua", info="starts the webserver"} + } } +-- api skeleton (implemented via soakbean's app.on(...)) +app.set = function(k,v) end +app.init = function() end + +-- load config +app.opts = require('config')(app) + + +app.runcmd(app) -- run clicmds + +-- init URL router app.url['^/data'] = '/data.lua' -- setup custom file endpoint -app.url['^/$'] = '/index.lua' -- alias for app.tpl( LoadAsset('index.html'), app ) -app.get('^/admin/$', app.template('admin/index.html') ) -- alias for app.tpl( LoadAsset('index.html'), app ) +app.url['^/$'] = '/page/index.lua' -- alias for app.tpl( LoadAsset('index.html'), app ) +app.get('^/design[/]?$', util.pagerender('page/design.html')) + +app.url['^/admin[/]?$'] = '/page/admin/index.lua' app.post('^/save', function(req,res,next) -- setup inline POST endpoint -- also .get(), .put(), .delete(), .options() @@ -43,23 +53,22 @@ app.post('^/save', function(req,res,next) -- setup inline POST endpoint end) app -- -.use( require("httpauth")() ) +.use( require("middleware/httpauth")() ) .use( require("json").middleware() ) -- try plug'n'play json API middleware .use( app.router( app.url ) ) -- try url router .use( app.response() ) -- try serve app response (if any) .use( function(req,next) Route() end) -- fallback default redbean fileserver -app.on('template', function(a,b,c,d,e) - print("TEMPLATE!") -end) - function OnHttpRequest() app.run() end -print("ja") ---function OnHttpRequest() --- if( not dir.serve("./experiences") ) then --- print("default") --- Route() --- end ---end --- +app.on('init', function() + if assert(unix.fork()) == 0 then + os.execute("ls ; sleep 5") + print("ok") + --local ok, headers, body = Fetch('http://127.0.0.1:8080/test') + end +end) + +OnServerStart = function() + app.init() -- this triggers init event +end diff --git a/src/.lua/cmd b/src/.lua/cmd new file mode 120000 index 0000000..9287aae --- /dev/null +++ b/src/.lua/cmd @@ -0,0 +1 @@ +../cmd \ No newline at end of file diff --git a/src/.lua/config.lua b/src/.lua/config.lua new file mode 100644 index 0000000..a181fa4 --- /dev/null +++ b/src/.lua/config.lua @@ -0,0 +1,51 @@ +local util = require('util') + +return function(app) + + local config = { -- default + name = "XRForge", + baseurl="/", + title="My XRForge experiences", + subtitle="Portable XR experiences for Phone, VRheadset & desktop.", + admin_title = "XRForge Admin", + admin_subtitle = "Manage your XR experiences here", + disk_dir = ".", + manyfold_instance_1 = "https://xrforge.isvery.ninja", + manyfold_instance_2 = "", + manyfold_instance_3 = "", + sync_interval = 30, + sync_strategy = "recent" + } + + local configfile = "xrforge.lua" + local savedconfig = util.readfile( app.bindir .. configfile, 'r', true) -- check local config + or LoadAsset(configfile) -- then internal saved config + + if savedconfig then + local eval = function(str) return load(str)() end + local status, result = pcall(eval, savedconfig ) -- Pass "string" as the first argument + if not status then + print("error: xrforge.lua contains errors:") + else + config = result -- overrule default config + end + end + + app.on('set', function(k,v) + if k == 'app.opts' then + app.opts = v + app.opts.updated = os.time() + local newconfig = "app.on('init', function()\n\tprint('config loaded')\nend)\n\nreturn " .. util.dump(app.opts) + newconfig = newconfig:gsub("^}$"," init = function() print('xrforge.lua config loaded') end\n}") + util.writefile( app.bindir .. configfile, newconfig ) + print("stored xrforge.lua") + end + end) + + -- store local config if not exist + if not util.readfile( app.bindir .. configfile, 'r', true) then + app.set('app.opts', config ) + end + + return config +end diff --git a/src/.lua/middleware b/src/.lua/middleware new file mode 120000 index 0000000..e7ecd4e --- /dev/null +++ b/src/.lua/middleware @@ -0,0 +1 @@ +../middleware \ No newline at end of file diff --git a/src/.lua/soakbean.lua b/src/.lua/soakbean.lua index 6fcf244..13ff4d7 100644 --- a/src/.lua/soakbean.lua +++ b/src/.lua/soakbean.lua @@ -23,7 +23,7 @@ sb = { sb.data[k] = (function(k,v) return function(a,b,c,d,e,f) v(a,b,c,d,e,f) - sb.pub(k,v) + sb.pub(k,v,a,b,c,d,e,f) end end)(k,v) else @@ -38,10 +38,14 @@ sb = { return sb.app end, - pub = function(k,v) + pub = function(k,v,a,b,c,d,e,f) if sb.handler[k] ~= nil then for i,handler in pairs(sb.handler[k]) do - coroutine.wrap(handler)(v,k) + if a then -- + coroutine.wrap(handler)(a,b,c,d,e,f) -- forward function args + else + coroutine.wrap(handler)(v,k) -- forward assignment + end end end end, @@ -187,13 +191,12 @@ sb = { end, init = function(app) - for k,v in pairs(argv) do - app.opts[ v:gsub("=.*","") ] = v:gsub(".*=","") - end - if( keys(app.cmd) > 0 ) then sb.runcmd(app) end end, runcmd = function(app) + for k,v in pairs(argv) do + app.opts[ v:gsub("=.*","") ] = v:gsub(".*=","") + end for k,v in pairs(app.opts) do if app.cmd[k] then local file = app.cmd[k].file diff --git a/src/.lua/util.lua b/src/.lua/util.lua index 2c4f421..c3b05d4 100644 --- a/src/.lua/util.lua +++ b/src/.lua/util.lua @@ -1,5 +1,26 @@ local util = { } +util.readfile = function(filename, mode, silent) + local file, err = io.open(filename, mode or "r") + if not file then + if not silent then print("Error opening file:", err) end + return + end + local content = file:read("*a") + file:close() + return content +end + +util.writefile = function(filename, content, mode) + local file, err = io.open(filename, mode or "w") -- Default write mode + if not file then + return print("Error opening file:", err) + end + file:write(content) + file:close() +end + + util.clone = function(orig) local orig_type = type(orig) local copy @@ -28,11 +49,20 @@ util.flatten = function(tbl, prefix, result) return result end +util.pagerender = function(file,data) + return function(req,res,next) + res.status(200) + res.header('content-type','text/html; charset=utf-8') + res.body( util.template( LoadAsset(file),data or app) ) + next() + end +end + util.template = function(content,data) - local finaldata = util.merge(app,{}) + local finaldata = util.merge(data or app,{}) finaldata = util.merge(finaldata, util.flatten(app.opts,"opts") ) - finaldata.header = app.tpl( LoadAsset('template/header.html'), finaldata ) - finaldata.footer = app.tpl( LoadAsset('template/footer.html'), finaldata ) + finaldata.header = app.tpl( LoadAsset('page/header.html'), finaldata ) + finaldata.footer = app.tpl( LoadAsset('page/footer.html'), finaldata ) return app.tpl( content, finaldata ) end diff --git a/src/admin/index.html b/src/admin/index.html deleted file mode 100644 index b074aa4..0000000 --- a/src/admin/index.html +++ /dev/null @@ -1,158 +0,0 @@ - - - -
- -|
-
-
- XR
- fĖ
oĖ
rĖ
gĖ
eĖ
- |
- - - | -
-
|
-
++
+ + âââââââââââââââââââââââââââââââââââââ + â Foo CLI ââ Foo Web â + âââââââââââââââââââââââââââââââââââââ + âââââââââââââââââââââââââââââââââââââ + â Foo Repository â + â ââââââââââ ââââââââââ âââââââââââ â + â â code â â issues â â patches â â + â ââââââââââ ââââââââââ âââââââââââ â + âââââââââââââââââââââââââââââââââââââĪ + â Foo Storage (Git) â + âââââââââââââââââââââââââââââââââââââ + âââââââââââââââââââââââââââââââââââââ + â Foo Node ââ Foo HTTPD â + ââââââââââââââââââĪâââââââââââââââââââĪ + â NoiseXK ââ HTTP + JSON â + âââââââââââââââââââââââââââââââââââââ ++
+ + âââââââââââââââââââââââââââââââââââââ + â Foo CLI ââ Foo Web â + âââââââââââââââââââââââââââââââââââââ + âââââââââââââââââââââââââââââââââââââ + â Foo Repository â + â ââââââââââ ââââââââââ âââââââââââ â + â â code â â issues â â patches â â + â ââââââââââ ââââââââââ âââââââââââ â + âââââââââââââââââââââââââââââââââââââĪ + â Foo Storage (Git) â + âââââââââââââââââââââââââââââââââââââ + âââââââââââââââââââââââââââââââââââââ + â Foo Node ââ Foo HTTPD â + ââââââââââââââââââĪâââââââââââââââââââĪ + â NoiseXK ââ HTTP + JSON â + âââââââââââââââââââââââââââââââââââââ ++
+ + âââââââââââââââââââââââââââââââââââââ + â Foo CLI ââ Foo Web â + âââââââââââââââââââââââââââââââââââââ + âââââââââââââââââââââââââââââââââââââ + â Foo Repository â + â ââââââââââ ââââââââââ âââââââââââ â + â â code â â issues â â patches â â + â ââââââââââ ââââââââââ âââââââââââ â + âââââââââââââââââââââââââââââââââââââĪ + â Foo Storage (Git) â + âââââââââââââââââââââââââââââââââââââ + âââââââââââââââââââââââââââââââââââââ + â Foo Node ââ Foo HTTPD â + ââââââââââââââââââĪâââââââââââââââââââĪ + â NoiseXK ââ HTTP + JSON â + âââââââââââââââââââââââââââââââââââââ ++
| + |
- XR
+
+ fĖ
oĖ
rĖ
gĖ
eĖ
- XR
fĖ
oĖ
rĖ
gĖ
eĖ
+
|
|
-
-
- XR
- fĖ
oĖ
rĖ
gĖ
eĖ
- |
- - - | -
-
|
-