updated docker to include janusstack/xrfragments repos + added tests + updated hooks
This commit is contained in:
parent
fcc6a4111e
commit
cdeb836d88
24 changed files with 1770 additions and 50 deletions
|
|
@ -53,6 +53,7 @@ $ docker run -t xrforge docker.io/coderofsalvation/xrforge:latest -v ./config:/c
|
|||
| `APPNAME` | `XRForge` | manyfold instance name |
|
||||
| `HOMEPAGE` | `/models` | show '/models' URL as homepage (use `/` for manyfold default) |
|
||||
| `THEME` | `default` | bootstrap theme |
|
||||
| 'JANUSXR' | `` | run local JanusXR stack (janus-server, janus-gateway, janusweb) |
|
||||
| `AFRAME_VERSION` | `1.7.0` | AFRAME version |
|
||||
| `GODOT_VERSION` | `4.4.1-stable`| godot editor version |
|
||||
| `GODOT_TEMPLATE_ZIP` | `` | godot template zip URL or file (default is empty godot project) |
|
||||
|
|
@ -188,3 +189,32 @@ For a quick dev-environment run:
|
|||
$ mkdir /dev
|
||||
$ manyfold/cli/manyfold.sh run -e DEV=1
|
||||
```
|
||||
|
||||
# JanusXR
|
||||
|
||||
When running xrforge with the `JANUSXR=1` env-flag, the opensource [JanusXR](https://janusxr.org) stack will be installed and started:
|
||||
|
||||
* [janus-server](https://github.com/janusvr/janus-server) for chat + syncing avatar positions
|
||||
* [janus-gateway](https://github.com/meetecho/janus-gateway) for video/audio
|
||||
* [janusweb](https://github.com/meetecho/janus-gateway) the viewer using the above services
|
||||
|
||||
> NOTE: consider this a fingers-crossed 'rolling release' installation, as this is not officially part of XRForge (just a helper for intranets).
|
||||
|
||||
Note that janus-server exposes a http websocket at port 5566, so you need to configure your reverse proxy as following:
|
||||
|
||||
* https://presence.foo.bar.com => 5566
|
||||
|
||||
> This assumes environment-var `FEDERATE_DRIVE_HOST` is set to `https://foo.bar.com` (`presence` subdomain is automatically prefixed by the installer)
|
||||
|
||||
#### persist JanusXR stack
|
||||
|
||||
When running the container run the following cmds to speed up the boot-time:
|
||||
|
||||
```
|
||||
$ docker cp xrforge:/mnt/janusweb .
|
||||
$ docker cp xrforge:/root/janus-server .
|
||||
```
|
||||
|
||||
then add the following flags to your docker cmd: `-v ./janusweb:/mnt/janusweb -v ./janus-server:/root/janus-server`
|
||||
|
||||
> That way JanusXR does not have to be installed every time during boot
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ run(){
|
|||
#-e NO_DEFAULTDB=true \
|
||||
#-e PUBLIC_HOSTNAME=localhost \
|
||||
#-e PUBLIC_PORT=80 \
|
||||
echo ${oci} run "$@" -p 8790:3214 -p 8791:3215 --name xrforge \
|
||||
#-e JANUSXR=1 \
|
||||
echo ${oci} run "$@" -p 8790:3214 -p 8791:3215 -p 5566:5566 -p 5577:5577 --name xrforge \
|
||||
-e SECRET_KEY_BASE=lkjwljlkwejrlkjek34k234l \
|
||||
-e DATABASE_ADAPTER=sqlite3 \
|
||||
-e FEDERATE_DRIVE_HOST=http://localhost:8791 \
|
||||
|
|
@ -49,6 +50,7 @@ overlayfs(){
|
|||
echocolor "[$APPNAME]" "applying filesystem overlay"
|
||||
cd /manyfold
|
||||
rsync -rvzi * /.
|
||||
#apply_patches
|
||||
}
|
||||
|
||||
# cron-like function using sleep (./manifold.sh infinite 3600 zip -r /backup.zip /)
|
||||
|
|
@ -99,6 +101,20 @@ start_hook_daemon(){
|
|||
#find /mnt | grep datapackage | xargs -n1 $0 hook inotify_MODIFY
|
||||
}
|
||||
|
||||
apply_patches(){
|
||||
echocolor "[$APPNAME]" "applying patches"
|
||||
for patch_file in /manyfold/patches/*.patch; do
|
||||
if patch -p1 -N --forward < "$patch_file"; then
|
||||
echo "✅ Successfully applied **$(basename "$patch_file")**"
|
||||
else
|
||||
echo "🛑 Failed to apply **$(basename "$patch_file")**"
|
||||
echo "Aborting script. Please inspect the failed patch and resolve conflicts."
|
||||
# Use 'exit' to stop the script on the first failure
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
db(){
|
||||
default(){
|
||||
|
|
@ -133,7 +149,7 @@ set_upload_path(){
|
|||
}
|
||||
|
||||
mount_dir(){
|
||||
find /mnt -type d -mindepth 1 -maxdepth 1 | while read dir; do
|
||||
find /mnt -type d -mindepth 1 -maxdepth 1 | grep -v janusweb | while read dir; do
|
||||
echocolor "[$APPNAME]" "mounting $dir as library"
|
||||
add_lib_to_db "$dir"
|
||||
done
|
||||
|
|
@ -235,21 +251,49 @@ force_public(){
|
|||
infinite 60 rails_query 'Model.find_each { |it| it.grant_permission_to("view", nil) }' &
|
||||
}
|
||||
|
||||
get_xrfragment_assets(){
|
||||
import_assets(){
|
||||
test -n "$NO_ASSETS" && return 0 # nothing to do here
|
||||
test -d /mnt/asset || {
|
||||
echocolor "fetching XR Fragments asset & templates"
|
||||
mkdir -p /mnt/asset/xrfragments /mnt/templates/xrfragments
|
||||
cd /tmp
|
||||
timeout 50 wget "https://codeberg.org/coderofsalvation/xrfragment/archive/main.zip"
|
||||
unzip main.zip
|
||||
cp -r xrfragment/assets/library /mnt/asset/xrfragments/\#1
|
||||
find xrfragment/assets/template -maxdepth 1 -mindepth 1 -type d | awk '{ system("cp -r "$0" /mnt/templates/xrfragments/#"(NR+1)) }'
|
||||
}
|
||||
add_lib_to_db /mnt/asset
|
||||
add_lib_to_db /mnt/templates
|
||||
}
|
||||
|
||||
janusxr(){
|
||||
start_server(){
|
||||
while sleep 2s; do
|
||||
flock -n "$@"
|
||||
echocolor "[$1]" "'$2 $3 $4' exited (why?)...restarting"
|
||||
done
|
||||
}
|
||||
|
||||
cd /root/corsanywhere
|
||||
npm install
|
||||
PORT=5577 start_server ~/.run-corsanywhere node server.js &
|
||||
|
||||
cd /root
|
||||
chmod +x janus_server-linux
|
||||
PORT=5566 start_server ~/.run-janus-server ./janus_server-linux &
|
||||
|
||||
## we should do this in nix/docker.nix but the image gets into GB's :/
|
||||
#which git || apk add git
|
||||
#which janus || apk add janus-gateway
|
||||
#which node || apk add nodejs
|
||||
#which bash || apk add bash
|
||||
#cd /root
|
||||
|
||||
## install server
|
||||
#test -d janus-server || git clone --depth 1 https://github.com/janusvr/janus-server
|
||||
#cd janus-server
|
||||
#test -d node_modules || { apk add npm && npm install; }
|
||||
#test -f config.js || ln -f /root/.config/janus-server/config.js .
|
||||
#start_server(){
|
||||
# while sleep 2s; do
|
||||
# flock -n ~/.janus-server node server.js
|
||||
# echocolor "[janus-server]" "'node server.js' exited (why?)...restarting"
|
||||
# done
|
||||
#}
|
||||
#test -f ~/.janus-server || start_server &
|
||||
}
|
||||
|
||||
init_database(){
|
||||
test -f ${db}.xrforgeinit && exit 0 # already inited
|
||||
sleep 3
|
||||
|
|
@ -261,7 +305,7 @@ init_database(){
|
|||
set_global model_path_template "replace('--- \"{creator}/{modelId} \"\\n','\\n',char(10))"
|
||||
set_upload_path
|
||||
#set_global about "$ABOUT"
|
||||
get_xrfragment_assets
|
||||
import_assets
|
||||
mount_dir
|
||||
BOOT_SCAN=1 scan_libraries &
|
||||
touch ${db}.xrforgeinit
|
||||
|
|
@ -276,6 +320,8 @@ boot(){
|
|||
set_homepage
|
||||
start_hook_daemon
|
||||
mount_rclone
|
||||
janusxr
|
||||
cp /root/templates/ARhome/* /mnt/janusweb/.
|
||||
force_public &
|
||||
|
||||
# enable development mode (disables template caching etc)
|
||||
|
|
|
|||
1
manyfold/mnt/janusweb/media/assets/webui/preview.html
Normal file
1
manyfold/mnt/janusweb/media/assets/webui/preview.html
Normal file
|
|
@ -0,0 +1 @@
|
|||
<janus-ui-settings-panels></janus-ui-settings-panels>
|
||||
20
manyfold/mnt/janusweb/media/assets/webui/preview.json
Normal file
20
manyfold/mnt/janusweb/media/assets/webui/preview.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"apps": {
|
||||
"inventory": "./apps/inventory/inventory.json",
|
||||
"editor": "./apps/editor/editor.json",
|
||||
"locomotion": "./apps/locomotion/locomotion.json",
|
||||
"virtualgamepad": "./apps/virtualgamepad/virtualgamepad.json",
|
||||
"buttons": "./apps/buttons/buttons.json",
|
||||
"xrmenu": "./apps/xrmenu/xrmenu.json"
|
||||
},
|
||||
"includes": [
|
||||
],
|
||||
"templates": {
|
||||
"janusweb.ui": "./preview.html"
|
||||
},
|
||||
"css": [
|
||||
"./themes/preview.css"
|
||||
],
|
||||
"scripts": [
|
||||
]
|
||||
}
|
||||
1377
manyfold/mnt/janusweb/media/assets/webui/themes/preview.css
Normal file
1377
manyfold/mnt/janusweb/media/assets/webui/themes/preview.css
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -17,5 +17,5 @@ test -n "$FEDERATE_DRIVE_CERT" && test -m "$FEDERATE_DRIVE_KEY" && {
|
|||
|
||||
set -x
|
||||
rclone serve http \
|
||||
--exclude .xrforge --poll-interval $FEDERATE_DRIVE_CACHE \
|
||||
--links --exclude .xrforge --poll-interval $FEDERATE_DRIVE_CACHE \
|
||||
--addr 0.0.0.0:$FEDERATE_DRIVE_PORT ${AUTH} ${SSL} $FEDERATE_DRIVE_PATH &> /var/log/rclone.log &
|
||||
|
|
|
|||
3
manyfold/root/hook.d/boot/runtests.sh
Executable file
3
manyfold/root/hook.d/boot/runtests.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
test -n "$RUNTESTS" || exit 0
|
||||
exec /test/runtests.sh
|
||||
|
|
@ -52,15 +52,20 @@ begin
|
|||
|
||||
# Iterate through the images array
|
||||
gltf['images'].each_with_index do |img, i|
|
||||
new_filename = "#{dir}/#{filenameWithoutExt}_img#{i}.png"
|
||||
old_filename = "#{dir}/.xrforge/#{filenameWithoutExt}_img#{i}.png"
|
||||
imgExts = ["jpg","png"]
|
||||
new_filename = "#{dir}/#{filenameWithoutExt}_img#{i}"
|
||||
old_filename = "#{dir}/.xrforge/#{filenameWithoutExt}_img#{i}"
|
||||
|
||||
# move file to modeldirectory (but dont overwrite if user overwrite it)
|
||||
if File.exist?(old_filename) && !File.exist?(new_filename)
|
||||
puts "✅ Renaming #{old_filename} -> #{new_filename}"
|
||||
File.rename(old_filename, new_filename)
|
||||
else
|
||||
puts "✅ Not overwriting (useruploaded) #{new_filename}"
|
||||
imgExts.each do |imgExt|
|
||||
# move file to modeldirectory (but dont overwrite if user overwrite it)
|
||||
if File.exist?("#{old_filename}.#{imgExt}") && !File.exist?("#{new_filename}.#{imgExt}")
|
||||
puts "✅ Renaming #{old_filename}.#{imgExt} -> #{new_filename}.#{imgExt}"
|
||||
File.rename( "#{old_filename}.#{imgExt}", "#{new_filename}.#{imgExt}" )
|
||||
else
|
||||
if File.exist?("#{new_filename}.#{imgExt}")
|
||||
puts "✅ Not overwriting (useruploaded) #{new_filename}.#{imgExt}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -48,15 +48,17 @@ begin
|
|||
|
||||
# Iterate through the images array
|
||||
gltf['images'].each_with_index do |img, i|
|
||||
new_filename = ""
|
||||
new_filename = "#{dir}/#{filenameWithoutExt}_img#{i}.png"
|
||||
|
||||
# move file to modeldirectory (but dont overwrite if user overwrite it)
|
||||
XRForge.log("🤔 checking #{new_filename}",logfile)
|
||||
if File.exist?(new_filename)
|
||||
XRForge.log("✅ importing #{new_filename} -> #{resource['path']}",logfile)
|
||||
img['uri'] = new_filename # NOTE: editing uri will cause assimp to drop image['name'] when exporting :/
|
||||
update = true
|
||||
imgExts = ["jpg","png"]
|
||||
imgExts.each do |imgExt|
|
||||
new_filename = "#{dir}/#{filenameWithoutExt}_img#{i}.#{imgExt}"
|
||||
if File.exist?(new_filename)
|
||||
XRForge.log("🤔 detected #{File.basename(new_filename)}",logfile)
|
||||
XRForge.log("✅ importing #{File.basename(new_filename)} -> #{resource['path']}",logfile)
|
||||
img['uri'] = new_filename # NOTE: editing uri will cause assimp to drop image['name'] when exporting :/
|
||||
update = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if update
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ begin
|
|||
# Check if a model file was found after the loop
|
||||
if ! model_file
|
||||
XRForge.log("❌ No suitable 3D file found for JanusXR-compatible experience", logfile)
|
||||
exit 0
|
||||
exit
|
||||
end
|
||||
|
||||
# Get the value of the environment variable FEDERATE_DRIVE_HOST
|
||||
|
|
@ -72,8 +72,11 @@ begin
|
|||
end
|
||||
end
|
||||
|
||||
private = data['keywords'].include?('singleuser') ? "private='true'" : ""
|
||||
if ! data['keywords']
|
||||
data['keywords'] = []
|
||||
end
|
||||
|
||||
private = data['keywords'].include?('singleuser') ? "private='true'" : ""
|
||||
# tags to JML rooms *REFACTOR PLEASE*
|
||||
use_local_asset = ""
|
||||
use_local_asset = data['keywords'].include?('room1') ? "use_local_asset=\"room1\"" : use_local_asset
|
||||
|
|
@ -86,14 +89,25 @@ begin
|
|||
use_local_asset = data['keywords'].include?('room2_pedestal') ? "use_local_asset=\"room2_pedestal\"" : use_local_asset
|
||||
use_local_asset = data['keywords'].include?('room2_narrow') ? "use_local_asset=\"room3_narrow\"" : use_local_asset
|
||||
|
||||
objects = objects + " <object pos=\"0 0 5\" rotation=\"-180 0 180\" lighting=\"false\" collision_id=\"experience\" id=\"experience\" />"
|
||||
objects = objects + " <object pos=\"0 0 5\" rotation=\"-180 0 180\" lighting=\"false\" collision_id=\"experience\" id=\"experience\" />"
|
||||
|
||||
#janusweb_src = "https://web.janusvr.com/janusweb.js"
|
||||
janusweb_src = ! ENV['DEV'].empty? ? "/janusweb/janusweb.js" : "/janusweb/janusweb.min.js"
|
||||
|
||||
server = ""
|
||||
if ENV['JANUSXR'] && ! ENV['JANUSXR'].empty?
|
||||
serverUrl = federate_drive_host.gsub("://","://presence.")
|
||||
.gsub(/:[0-9].*/,"")
|
||||
.gsub(/\/$/,"")
|
||||
server = "server=#{serverUrl}:5566/"
|
||||
end
|
||||
|
||||
jml = <<~JML
|
||||
<FireBoxRoom>
|
||||
<Assets>
|
||||
#{assets}
|
||||
</Assets>
|
||||
<Room autogenerate="true" #{use_local_asset} #{private}>
|
||||
<Room autogenerate="true" #{use_local_asset} #{private} #{server} showavatar="false" voip="none">
|
||||
#{objects}
|
||||
</Room>
|
||||
</FireBoxRoom>
|
||||
|
|
@ -120,22 +134,34 @@ begin
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>janusxr room</title>
|
||||
<title>#{data['title']} - JanusXR</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="https://web.janusvr.com/janusweb.js"></script>
|
||||
<janus-viewer>
|
||||
<janus-viewer homepage="/" autostart="false">
|
||||
#{jml}
|
||||
</janus-viewer>
|
||||
|
||||
<!-- map query args as attributes -->
|
||||
<!-- map URL query args to room-attributes -->
|
||||
<script>
|
||||
args = new URLSearchParams(document.location.search)
|
||||
for( const [k,v] of args.entries()) document.querySelector("Room").setAttribute(k,v)
|
||||
</script>
|
||||
<script src="#{janusweb_src}"></script>
|
||||
<script>
|
||||
elation.config.set("engine.assets.corsproxy", "#{federate_drive_host.gsub(/:[0-9].*/,"")}:5577")
|
||||
elation.config.set("janusweb.network.host", "#{federate_drive_host.gsub(/:[0-9].*/,"")}:5566")
|
||||
elation.config.set("dependencies.host", "#{federate_drive_host.gsub(/:[0-9].*/,"")}");
|
||||
let opts = {
|
||||
uiconfig: `/janusweb/media/assets/webui/${ args.get("networking") == "false" ? "preview" : "default"}.json`,
|
||||
// for more opts see getClientArgs() in
|
||||
// https://github.com/jbaicoianu/janusweb/blob/master/scripts/client.js
|
||||
}
|
||||
// start!
|
||||
elation.janusweb.init(opts)
|
||||
</script>
|
||||
|
||||
<!-- archive.org hints -->
|
||||
<a href="#{federate_drive_host}/#{model_file.gsub("#","%23")}"></a>
|
||||
<a href="#{federate_drive_host}/#{dirPublic}/#{model_file.gsub("#","%23")}"></a>
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/sh
|
||||
|
||||
which rclone &>/dev/null || { echo "[!] rclone not installed"; exit 0; }
|
||||
which rclone &>/dev/null || { echo "❌ rclone not installed"; exit 1; }
|
||||
|
||||
test -d /mnt/models || { echo "[!] /mnt/models does not exist"; exit 0; }
|
||||
test -d /mnt/experiences || { echo "❌ /mnt/models does not exist"; exit 1; }
|
||||
|
|
|
|||
24
manyfold/test/1000-extract-textures.sh
Executable file
24
manyfold/test/1000-extract-textures.sh
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh
|
||||
experience=/mnt/templates/xrfragments/\#4
|
||||
dir=/tmp/hook-extract-textures
|
||||
xrfdir=$dir/.xrforge
|
||||
|
||||
which assimp || {
|
||||
echo "❌ assimp was not installed";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
mkdir -p $xrfdir || true
|
||||
rm $experience/*_img*.* || true
|
||||
/root/hook.d/experience_updated/*-extract-textures.rb $experience/datapackage.json 2>&1 \
|
||||
| grep "Wrote texture 0" || {
|
||||
echo "❌ $experience/murial3D_img0.png was not written";
|
||||
exit 1;
|
||||
}
|
||||
test -f $experience/murial3D_img0.png || {
|
||||
echo "❌ $experience/murial3D_img0.png was not written";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
rm -rf $dir
|
||||
exit 0
|
||||
18
manyfold/test/1050-compile-textures.sh
Executable file
18
manyfold/test/1050-compile-textures.sh
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/sh
|
||||
experience=/mnt/templates/xrfragments/\#4
|
||||
dir=/tmp/hook-compile-textures
|
||||
xrfdir=$dir/.xrforge
|
||||
|
||||
which assimp || {
|
||||
echo "❌ assimp was not installed";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
mkdir -p $xrfdir || true
|
||||
/root/hook.d/experience_updated/*-compile-textures.rb $experience/datapackage.json 2>&1 | grep "wrote output" || {
|
||||
echo "❌ $experience/murial3D.glb was not updated";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
rm -rf $dir
|
||||
exit 0
|
||||
12
manyfold/test/11-hook-reset-log.sh
Executable file
12
manyfold/test/11-hook-reset-log.sh
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
dir=/tmp/11-hook
|
||||
xrfdir=$dir/.xrforge
|
||||
mkdir -p $xrfdir
|
||||
echo 1 > $xrfdir/log.txt
|
||||
/root/hook.d/experience_updated/*-reset-log.sh $dir/datapackage.json
|
||||
test "$(cat $xrfdir/log.txt)" = "1" && {
|
||||
echo "❌ log.txt was not reset";
|
||||
exit 1;
|
||||
}
|
||||
rm -rf $dir
|
||||
exit 0
|
||||
12
manyfold/test/300-package_godot_zip.sh
Executable file
12
manyfold/test/300-package_godot_zip.sh
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
dir=/tmp/hook-package_godot_zip
|
||||
xrfdir=$dir/.xrforge
|
||||
mkdir -p $xrfdir
|
||||
touch $xrfdir/foo.glb
|
||||
/root/hook.d/experience_updated/*-package_godot_zip.sh $dir/datapackage.json
|
||||
test -f $xrfdir/godot.zip || {
|
||||
echo "❌ godot.zip was not created";
|
||||
exit 1;
|
||||
}
|
||||
rm -rf $dir
|
||||
exit 0
|
||||
36
manyfold/test/300-package_janusxr.sh
Executable file
36
manyfold/test/300-package_janusxr.sh
Executable file
|
|
@ -0,0 +1,36 @@
|
|||
#!/bin/sh
|
||||
id=janusxr
|
||||
dir=/tmp/hook-package_$id
|
||||
xrfdir=$dir/.xrforge
|
||||
mkdir -p $xrfdir
|
||||
|
||||
testjml(){
|
||||
/root/hook.d/experience_updated/*-package_$id.rb $dir/datapackage.json
|
||||
test -f $xrfdir/scene.jml || {
|
||||
echo "❌ scene.jml was not created";
|
||||
exit 1;
|
||||
}
|
||||
test -f $xrfdir/janusxr.html || {
|
||||
echo "❌ janusxr.html was not created";
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
echo "### test xrfragment heuristic"
|
||||
touch $dir/foo.png
|
||||
touch $dir/foo.glb
|
||||
echo '{
|
||||
"image":"foo.png",
|
||||
"resources": [{"path":"foo.glb"}]
|
||||
}' > $dir/datapackage.json
|
||||
testjml
|
||||
|
||||
echo "### test first-suitable-3d-file heuristic"
|
||||
rm $dir/foo.png
|
||||
echo '{
|
||||
"resources": [{"path":"foo.glb"}]
|
||||
}' > $dir/datapackage.json
|
||||
testjml
|
||||
|
||||
rm -rf $dir
|
||||
exit 0
|
||||
15
manyfold/test/janus-server
Executable file
15
manyfold/test/janus-server
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
test $(ps aux | grep run-janus-server | wc -l) = 2 || {
|
||||
echo "❌ janus-server is not running"
|
||||
exit 1;
|
||||
}
|
||||
echo "✅ janus-server is running"
|
||||
|
||||
test $(ps aux | grep run-corsanywhere | wc -l) = 2 || {
|
||||
echo "❌ corsanywhere is not running"
|
||||
exit 1;
|
||||
}
|
||||
echo "✅ corsanywhere is running"
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,13 +1,16 @@
|
|||
#!/bin/sh
|
||||
|
||||
test -z "$RUNTESTS" && exit 0 # nothing to do
|
||||
|
||||
echo ""
|
||||
echo "[!] RUNTESTS=1 was set "
|
||||
echo "[.] running tests in /test/*"
|
||||
echo "running tests in /test/*"
|
||||
echo ""
|
||||
|
||||
find -L /test/* -type f -executable -maxdepth 1 | while read testscript; do
|
||||
echo "[.] test: "$testscript
|
||||
$testscript "$@" 2>&1 | awk '{ print " | "$0 }'
|
||||
error(){ echocolor "❌" "$*"; exit 1; }
|
||||
ok(){ echocolor "✅" "$*"; return 0; }
|
||||
echocolor(){ printf "\033[96m%s\033[0m \033[95m%s\033[0m %s\n" "$1" "$2" "$3"; }
|
||||
|
||||
find -L /test/* -type f -executable -maxdepth 1 | grep -v runtests | sort -V | while read testscript; do
|
||||
echo "🛠 $testscript"
|
||||
{
|
||||
$testscript "$@" 2>&1 && ok "$testscript" || error "$testscript"
|
||||
} | awk '{ print " | "$0 }'
|
||||
done
|
||||
|
|
|
|||
|
|
@ -14,7 +14,9 @@ class Components::PreviewFrame < Components::Base
|
|||
end
|
||||
|
||||
def view_template
|
||||
a href: "/view?#{model_model_file_path(@file.model, @file, format: @file.extension)}", target:"_blank" do
|
||||
|
||||
a href: ENV['FEDERATE_DRIVE_HOST']+"/"+@file.model.library.name+"/"+@file.model.path.gsub("#","%23")+"/.xrforge/janusxr.html?networking=false", target: "_blank" do
|
||||
#a href: "/view?#{model_model_file_path(@file.model, @file, format: @file.extension)}", target:"_blank", alt: "launch single-user experience" do
|
||||
if @file
|
||||
local
|
||||
elsif @object.remote?
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
<%= yield :page_header %>
|
||||
|
||||
<div class="row row-cols-md-2 mt-2">
|
||||
<div class="col-md-9" id="item_list">
|
||||
|
||||
<% if ENV['DEV'] %>
|
||||
<a target="_blank" href="<%=ENV['FEDERATE_DRIVE_HOST']%>/janusweb/index.html#janus.url=<%=ENV['FEDERATE_DRIVE_HOST']%>/janusweb/portalAR.xml">
|
||||
<img src="/assets/lobby.png" style="width:100%; border-radius:10px;margin-bottom:17px"/>
|
||||
</a>
|
||||
<% end %>
|
||||
|
||||
<%= yield :items %>
|
||||
</div>
|
||||
<div class="col-md-3" id="sidebar">
|
||||
<% action_content = yield :actions %>
|
||||
<%= card(:secondary, t(".actions_heading"), class: "action-card") { action_content } if action_content.present? %>
|
||||
<%= yield :sidebar %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% parent_layout "application" %>
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
<div class="row row-cols-md-2 mt-2">
|
||||
<div class="col-md-9" id="item_list">
|
||||
|
||||
<% if @locked_files > 0 %>
|
||||
<div class="alert alert-info"><%= t(".preview", count: @locked_files) %></div>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ Rails.application.config.to_prepare do
|
|||
# Use `write` to set the new time. Caching a string representation is often safer/easier.
|
||||
Rails.cache.write(cache_key, now.to_s, expires_in: ttl + 3.second)
|
||||
|
||||
puts "[app/config/initializers/xrforge.rb] running hook\n"
|
||||
puts "[app/config/initializers/xrforge.rb] running hook #{file}\n"
|
||||
Bundler.with_unbundled_env do
|
||||
#`TS_SLOTS=5 ts /manyfold/cli/manyfold.sh hook experience_updated #{file} &`
|
||||
`/manyfold/cli/manyfold.sh hook experience_updated #{file}`
|
||||
|
|
|
|||
BIN
manyfold/usr/src/app/public/assets/lobby.png
Normal file
BIN
manyfold/usr/src/app/public/assets/lobby.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 472 KiB |
|
|
@ -38,6 +38,68 @@ let
|
|||
finalImageTag = "latest";
|
||||
};
|
||||
|
||||
#### JANUSXR Stack
|
||||
|
||||
janusweb = builtins.fetchTarball {
|
||||
url = "https://github.com/coderofsalvation/janusweb/releases/download/1.5.56-xrf/janusweb-1.5.56.tar.gz";
|
||||
# Get the SHA256 hash by running: nix-prefetch-url --unpack <URL>
|
||||
sha256 = "0zkmfv07zxdf1nkhgr4g959fj86p2yp9f7n1ll1zyhlm186sfh31";
|
||||
};
|
||||
|
||||
# Fetch the source from the GitHub tag
|
||||
corsanywhere = pkgs.fetchzip {
|
||||
url = "https://github.com/Rob--W/cors-anywhere/archive/0.4.4.tar.gz";
|
||||
# You need to calculate the correct SHA256 hash for version 0.4.4
|
||||
# You can get this by running 'nix-prefetch-url --unpack https://github.com/Rob--W/cors-anywhere/archive/0.4.4.tar.gz'
|
||||
sha256 = "0zb3xzlpbc400rvibm66qb27y0lla8sml1ns41ksxcc0l0kp0bwz";
|
||||
};
|
||||
|
||||
janusServer = pkgs.fetchurl {
|
||||
url = "https://github.com/janusvr/janus-server/releases/download/v0.2.1/janus_server-linux";
|
||||
# You can calculate the hash using: nix-prefetch-url https://...
|
||||
sha256 = "1rrmabvqn4lm7c2k1q2crqwyk7lvpmfihc3hx3qx2hzsjyp5v3ja";
|
||||
name = "janus_server-linux";
|
||||
};
|
||||
|
||||
## 2. Create a minimal derivation to make the file executable
|
||||
#janusServerBin = pkgs.stdenv.mkDerivation {
|
||||
# pname = "janus-server";
|
||||
# version = "1.0";
|
||||
# src = janusServer;
|
||||
# dontUnpack = true;
|
||||
# dontBuild = true;
|
||||
# installPhase = ''
|
||||
# mkdir -p $out/bin
|
||||
# cp $src $out/bin/janus_server-linux
|
||||
# chmod +x $out/bin/janus_server-linux
|
||||
# '';
|
||||
#};
|
||||
|
||||
janus = pkgs.runCommand "janusweb-content" {} ''
|
||||
mkdir -p $out/mnt/janusweb $out/root/corsanywhere $out/root
|
||||
cp -rT ${janusweb} $out/mnt/janusweb
|
||||
cp -rT ${corsanywhere} $out/root/corsanywhere/.
|
||||
cp -rT ${janusServer} $out/root/janus_server-linux
|
||||
'';
|
||||
|
||||
#### XR FRAGMENTS
|
||||
|
||||
## $ nix-shell -p nix-prefetch-git --command 'nix-prefetch-git https://codeberg.org/coderofsalvation/xrfragment.git <commit>'
|
||||
xrfragmentsRepo = pkgs.fetchFromGitea {
|
||||
"domain" = "codeberg.org";
|
||||
"owner" = "coderofsalvation";
|
||||
"repo" = "xrfragment";
|
||||
"rev" = "823736a74dbdabd46924ebbc3dc58a076c3c900b";
|
||||
"hash" = "sha256-P/RVwoDu0EYfwc0n2h1f4j0JZshtE4AtQsTU9iEkAcA=";
|
||||
};
|
||||
|
||||
xrfragments = pkgs.runCommand "xrfragments-content" {} ''
|
||||
mkdir -p $out/mnt/asset/xrfragments $out/mnt/templates/xrfragments
|
||||
cp -r ${xrfragmentsRepo}/assets/library $out/mnt/asset/xrfragments/\#1
|
||||
find ${xrfragmentsRepo}//assets/template -maxdepth 1 -mindepth 1 -type d | awk '{ system("cp -r "$0" '$out'/mnt/templates/xrfragments/#"(NR+1)) }'
|
||||
'';
|
||||
|
||||
|
||||
## generate the reproducable blob below via:
|
||||
## $ nix-shell -p nix-prefetch-github --command 'nix-prefetch-github assimp assimp --rev e778c84cd62bc8b38d8e491ad3d2c27cb8ed37d5'
|
||||
#assimpSrc = pkgs.fetchFromGitHub {
|
||||
|
|
@ -66,19 +128,23 @@ rec
|
|||
# add nix pkgs + local files
|
||||
copyToRoot = pkgs.buildEnv {
|
||||
name = "image-root";
|
||||
pathsToLink = ["/manyfold" "/bin" ];
|
||||
pathsToLink = ["/manyfold" "/bin" "/mnt" "/root"];
|
||||
paths = [
|
||||
#pkgs.pkgsStatic.rsync
|
||||
pkgs.rsync
|
||||
pkgs.sqlite
|
||||
pkgs.rclone
|
||||
pkgs.fuse3
|
||||
pkgs.janus-gateway # webrtc voip for JanusXR
|
||||
pkgs.nodejs_20 # for corsanywhere
|
||||
#pkgs.acl # getfacl e.g.
|
||||
#pkgs.inotify-tools # inotifywait e.g.
|
||||
pkgs.zip # inotifywait e.g.
|
||||
pkgs.assimp
|
||||
##pkgs.ts # job management
|
||||
#myAssimp # updated build of assimp
|
||||
janus
|
||||
xrfragments
|
||||
../.
|
||||
];
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue