added upload media-files

This commit is contained in:
Leon van Kammen 2025-12-16 14:08:55 +01:00
parent cdeb836d88
commit e505d65776

View file

@ -1,6 +1,7 @@
#!/usr/bin/env ruby
require 'json'
require 'erb'
require_relative './../../xrforge.rb'
# Check if a filename is provided
@ -9,8 +10,17 @@ if ARGV.length != 1
exit 1
end
filename = ARGV[0]
filename = ARGV[0]
JMLHeuristic = /<fireboxroom>.*?<\/fireboxroom>/im
metadataRegex= /(^<!--|<fireboxroom).*/im
templateDir = File.dirname(__FILE__)+"/../../templates/"
$links = []
def addLink(url)
$links.push(url)
return url
end
begin
@ -37,134 +47,145 @@ 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
end
# Get the value of the environment variable FEDERATE_DRIVE_HOST
federate_drive_host = ENV['FEDERATE_DRIVE_HOST']
autogenerate = true
janusweb_src = ENV['DEV'] ? "/janusweb/janusweb.js" : "/janusweb/janusweb.min.js"
if data['description'] && data['description'].match(JMLHeuristic)
if data['description'].match(/autogenerate=["']false["']/i)
XRForge.log("✅ autogenerate='false' found in JML..keeping this JML",logfile)
if ! data['description'].match(/<room.* autogenerate.*>/i)
XRForge.log("✅ autogenerate attribute found in JML..keeping this JML",logfile)
autogenerate = false
jmlMatch = data['description'].match(JMLHeuristic)
jml = jmlMatch[0]
end
end
if autogenerate
assets = "<assetobject id=\"experience\" src=\"#{federate_drive_host}/#{dirPublic}/#{model_file.gsub("#","%23")}\"/>\n"
objects = ""
assets = ""
objects = ""
startpos = ""
audiovisual = false
showavatar = "showavatar=\"false\""
data['keywords'] = data['keywords'] || []
data['description'] = data['description'] || ""
if data['description'].strip().length == 0
data['description'] = "Click the edit-button to change this description, or add the 'nodescription' tag to hide this."
end
# tags to JML rooms
use_local_asset = ""
use_local_asset = data['keywords'].include?('room1') ? "room1" : use_local_asset
use_local_asset = data['keywords'].include?('room2') ? "room2" : use_local_asset
use_local_asset = data['keywords'].include?('room3') ? "room3" : use_local_asset
use_local_asset = data['keywords'].include?('room4') ? "room4" : use_local_asset
use_local_asset = data['keywords'].include?('room5') ? "room5" : use_local_asset
use_local_asset = data['keywords'].include?('room6') ? "room5" : use_local_asset
use_local_asset = data['keywords'].include?('room1_pedestal') ? "room1_pedestal" : use_local_asset
use_local_asset = data['keywords'].include?('room2_pedestal') ? "room2_pedestal" : use_local_asset
use_local_asset = data['keywords'].include?('room2_narrow') ? "room3_narrow" : use_local_asset
# private room or not
if data['keywords'].include?('singleuser')
private = "private=\"true\""
data['keywords'] = data['keywords'] || []
showavatar = "showavatar=\"false\""
end
if data['keywords'].include?('showavatar')
showavatar = "showavatar=\"false\""
end
# detect audio track sidecarfile as per XR Fragment spec: https://xrfragment.org/#%F0%9F%93%9C%20level0%3A%20File
xrf_ext = File.extname(model_file)
xrf_base = File.basename(model_file, xrf_ext)
xrf_ext = model_file ? File.extname(model_file) : ""
xrf_base = model_file ? File.basename(model_file, xrf_ext) : ""
# remove the metadata from the description
description = data['description'].gsub(metadataRegex,"").strip()
data['resources'].each do |resource|
ext = File.extname(resource['path'])
if ext.match(/mp3/i)
base = File.basename(resource['path'], ext)
if base == xrf_base
XRForge.log("✅ XR Fragments side-car file found: #{resource['path']}",logfile)
assets = assets + " <assetsound id=\"soundtrack\" src=\"#{federate_drive_host}/#{dirPublic}/#{resource["path"]}\"/>\n"
objects = objects + "<sound id=\"soundtrack\" loop=\"true\"/>\n"
audiovisual = model_file ? false : true
base = File.basename(resource['path'], ext)
soundtrackUrl = addLink("#{federate_drive_host}/#{dirPublic}/#{resource["path"]}")
assets += " <assetsound id=\"soundtrack\" src=\"#{soundtrack_url}\"/>\n"
objects += "<sound id=\"soundtrack\" loop=\"true\"/>\n"
end
if ext.match(/(png|jpg|jpeg|gif)/i)
imgbase = File.basename(resource['path'])
if File.basename( data['image'] || "") != imgbase && # ignore thumbnail
xrf_base != imgbase # ignore XR Fragments thumbnail
audiovisual = model_file ? false : true
base = File.basename(resource['path'], ext)
videoSrc = addLink("#{federate_drive_host}/#{dirPublic}/#{resource["path"]}")
assets += "<assetimage id=\"image\" src=\"#{videoSrc}\" loop=\"true\" auto_play=\"true\"/>\n"
objects += " <Object cull_face=\"none\" id=\"rplane\" js_id=\"image\" lighting=\"false\" pos=\"0 6.5 5.5\" scale=\"4 4 1\" image_id=\"image\"/>\n"
end
end
if ext.match(/mp4/i) || ext.match(/webm/i)
audiovisual = model_file ? false : true
base = File.basename(resource['path'], ext)
videoSrc = addLink("#{federate_drive_host}/#{dirPublic}/#{resource["path"]}")
assets += "<assetvideo id=\"video\" src=\"#{videoSrc}\" loop=\"true\" auto_play=\"true\"/>\n"
objects += " <Object cull_face=\"none\" id=\"rplane\" js_id=\"video\" lighting=\"false\" pos=\"0 6.5 5.5\" scale=\"4 4 1\" video_id=\"video\"/>\n"
end
end
if ! data['keywords']
data['keywords'] = []
if audiovisual
# TODO: copy files from a heuristic-based folder instead hardcoding it here
startpos = "pos=\"0 0 -10\""
use_local_asset = "room5"
rplaneSrc = addLink("#{federate_drive_host}/#{dirPublic}/roundedplane.glb")
system("cp /root/templates/audiovisual/roundedplane.glb #{dir}/.")
assets += " <assetobject id=\"rplane\" src=\"#{rplaneSrc}\"/>\n"
objects += " <Object cull_face=\"none\" id=\"rplane\" js_id=\"text_rplane\" lighting=\"false\" pos=\"2.69 1.84 -3.37\" rotation=\"0 45 0\" scale=\"1.6 1 1\"/>\n"
if ! data['keywords'].include?( use_local_asset )
data['keywords'].push( use_local_asset )
end
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
use_local_asset = data['keywords'].include?('room2') ? "use_local_asset=\"room2\"" : use_local_asset
use_local_asset = data['keywords'].include?('room3') ? "use_local_asset=\"room3\"" : use_local_asset
use_local_asset = data['keywords'].include?('room4') ? "use_local_asset=\"room4\"" : use_local_asset
use_local_asset = data['keywords'].include?('room5') ? "use_local_asset=\"room5\"" : use_local_asset
use_local_asset = data['keywords'].include?('room6') ? "use_local_asset=\"room5\"" : use_local_asset
use_local_asset = data['keywords'].include?('room1_pedestal') ? "use_local_asset=\"room1_pedestal\"" : use_local_asset
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\" />"
#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/"
# generate thumbnail if no thumbnail
if data['resources'].length == 1
thumbfile = "thumbnail.jpg"
if model_file
thumbfile = "#{xrf_base}.jpg"
end
system("/root/bin/random_thumbnail.sh","/root/templates/thumbnailseed.jpg","#{dir}/#{thumbfile}","6","2>&1 | sed 's|/root/template||g'")
data['image'] = thumbfile
XRForge.log("✅ generated thumbnail", logfile)
end
jml = <<~JML
<FireBoxRoom>
<Assets>
#{assets}
</Assets>
<Room autogenerate="true" #{use_local_asset} #{private} #{server} showavatar="false" voip="none">
#{objects}
</Room>
</FireBoxRoom>
<!-- archive.org hints -->
<a href="#{federate_drive_host}/#{dirPublic}/#{model_file.gsub("#","%23")}"></a>
JML
if description && !data['keywords'].include?('nodescription')
objects += " <Paragraph pos=\"2.8 1 -3.21\" fwd=\"0 0 1\" lighting=\"false\" rotation=\"180 -45 180\" col=\"0.5 0.8 0.5\" scale=\"2 2 2\" font_size=\"50\" locked=\"false\">#{description}</Paragraph>\n"
end
data['description'] = data['description'] ? data['description'] : "your description here\n"
data['description'] = <<~DESCRIPTION#{data['description']}
<!-- Hi there! Below is autogenerated JanusXR Markup (JML). -->
<!-- If you want to tweak it, then first disable autogeneration -->
<!-- How? make sure to set autogenerate to "false" (see room-tag below) -->
<!-- -->
<!-- JML info: -->
<!-- https://coderofsalvation.github.io/janus-guide/#/examples/markup -->
<!-- https://janusxr.org/docs/build/introtojml/index.html -->
if model_file
objectSrc = "#{federate_drive_host}/#{dirPublic}/#{model_file.gsub("#","%23")}"
if ! $links.include?(objectSrc)
objectSrc = addLink(objectSrc)
assets += " <assetobject id=\"experience\" src=\"#{objectSrc}\"/>\n"
objects += " <object pos=\"0 0 5\" rotation=\"-180 0 180\" lighting=\"false\" collision_id=\"experience\" id=\"experience\" />"
end
end
#{jml}
DESCRIPTION
use_local_asset = use_local_asset ? "use_local_asset=\"#{use_local_asset}\"" : ""
jml = ERB.new( File.read( templateDir+"JML/room.erb" ) ).result(binding)
data['description'] = data['description'] ? data['description'].gsub(metadataRegex,"") : ""
data['description'] += "\n\n" + ERB.new( File.read( templateDir+"JML/header.erb" ) ).result(binding)
data['description'] += jml
File.write("datapackage.json", JSON.pretty_generate(data) )
end
html = <<~HTML
<!DOCTYPE html>
<html>
<head>
<title>#{data['title']} - JanusXR</title>
</head>
<body>
<janus-viewer homepage="/" autostart="false">
#{jml}
</janus-viewer>
<!-- 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}/#{dirPublic}/#{model_file.gsub("#","%23")}"></a>
</body>
</html>
HTML
html = ERB.new( File.read( templateDir+"JML/client.html") ).result(binding)
File.write('.xrforge/janusxr.html', html)
File.write('.xrforge/scene.jml', jml)