Compare commits
2 Commits
176adc61fd
...
919a888386
Author | SHA1 | Date |
---|---|---|
Leon van Kammen | 919a888386 | |
Leon van Kammen | bbc88be954 |
|
@ -22,6 +22,7 @@ OUTPUT=/mnt/run/$PID # com/isoterminal/feat/javascript.js writes output here
|
||||||
touch $OUTPUT
|
touch $OUTPUT
|
||||||
echo -n "PID=$PID; $javascript" > /dev/browser/js
|
echo -n "PID=$PID; $javascript" > /dev/browser/js
|
||||||
# todo watch file
|
# todo watch file
|
||||||
|
sleep 0.1
|
||||||
cat $OUTPUT
|
cat $OUTPUT
|
||||||
rm $OUTPUT
|
rm $OUTPUT
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ help_tips(){
|
||||||
}
|
}
|
||||||
|
|
||||||
export TERM=xterm-256color
|
export TERM=xterm-256color
|
||||||
export PS1="\[\033[38;5;165m\]> \[\033[0m\]"
|
export PS1="\[\e[36m\]> \[\e\[0m\]"
|
||||||
|
|
||||||
# aliases
|
# aliases
|
||||||
alias ls='ls -ha -w100'
|
alias ls='ls -ha -w100'
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
hook(){
|
hook(){
|
||||||
test -z "$1" && { echo "usage: hook <cmd_or_jsfunction> [args]"; return 0; }
|
test -z "$1" && { echo "usage: hook <cmd_or_jsfunction> [args]"; return 0; }
|
||||||
|
logger "$ hook $*"
|
||||||
cmd=$1
|
cmd=$1
|
||||||
shift
|
shift
|
||||||
test -d ~/hook.d/$cmd && {
|
test -d ~/hook.d/$cmd && {
|
||||||
find ~/hook.d/$cmd/ -type f -executable | while read hook; do
|
find -L ~/hook.d/$cmd/ -type f -executable -maxdepth 1 | while read hook; do
|
||||||
|
logger " |+ hook $hook $*"
|
||||||
{ $hook "$@" || true; } | awk '{ gsub(/\/root\/\//,"",$1); $1 = sprintf("%-40s", $1)} 1'
|
{ $hook "$@" || true; } | awk '{ gsub(/\/root\/\//,"",$1); $1 = sprintf("%-40s", $1)} 1'
|
||||||
done
|
done
|
||||||
}
|
} &> ~/hook.d/log.txt
|
||||||
}
|
}
|
||||||
|
|
||||||
alert(){
|
alert(){
|
||||||
|
@ -20,7 +22,11 @@ alert(){
|
||||||
|
|
||||||
confirm(){
|
confirm(){
|
||||||
test -z "$1" && { echo "usage: confirm <question>"; return 0; }
|
test -z "$1" && { echo "usage: confirm <question>"; return 0; }
|
||||||
read -p "$(printf "\033[0m")[?] [38;5;165m$1 [y/n] $(printf "\033[0m")" y
|
if test -n "$BROWSER"; then
|
||||||
|
jsh confirm "$1"
|
||||||
|
else
|
||||||
|
read -p "$(printf "\033[0m")[?] [38;5;165m$1 [y/n] $(printf "\033[0m")" y
|
||||||
|
fi
|
||||||
test $y = y && echo true && return 0
|
test $y = y && echo true && return 0
|
||||||
test $y = y || echo false
|
test $y = y || echo false
|
||||||
hook confirm $1 $y
|
hook confirm $1 $y
|
||||||
|
@ -29,7 +35,11 @@ confirm(){
|
||||||
prompt(){
|
prompt(){
|
||||||
test -z "$1" && { echo "usage: prompt <question> [answer_default]"; return 0; }
|
test -z "$1" && { echo "usage: prompt <question> [answer_default]"; return 0; }
|
||||||
test -n "$2" && answer="[$2] " && answer_fallback="$2"
|
test -n "$2" && answer="[$2] " && answer_fallback="$2"
|
||||||
read -p "$(printf "\033[0m")[?] [38;5;165m$1: $answer $(printf "\033[0m")" answer
|
if test -n "$BROWSER"; then
|
||||||
|
jsh prompt "$1" "$answer_fallback"
|
||||||
|
else
|
||||||
|
read -p "$(printf "\033[0m")[?] [38;5;165m$1: $answer $(printf "\033[0m")" answer
|
||||||
|
fi
|
||||||
test -z "$answer" && answer="$answer_fallback"
|
test -z "$answer" && answer="$answer_fallback"
|
||||||
echo "$answer"
|
echo "$answer"
|
||||||
hook prompt $1 $answer
|
hook prompt $1 $answer
|
||||||
|
|
|
@ -9,6 +9,13 @@ test -d /dev/browser || {
|
||||||
ln -fs /mnt/root /root
|
ln -fs /mnt/root /root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setup_clipboard(){
|
||||||
|
test -d /mnt/clipboard || {
|
||||||
|
mkdir /mnt/clipboard
|
||||||
|
echo "files appear here when dragdropping- or copy/pasting a file into the 3D scene (minimize in non-immersive mode)" > /mnt/clipboard/README.md
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setup_links(){
|
setup_links(){
|
||||||
ln -fs /etc/motd ~/.motd
|
ln -fs /etc/motd ~/.motd
|
||||||
ln -fs /mnt/profile.browser ~/.profile.browser
|
ln -fs /mnt/profile.browser ~/.profile.browser
|
||||||
|
@ -50,6 +57,7 @@ test -d /dev/browser || {
|
||||||
|
|
||||||
move_root_to_9pfs
|
move_root_to_9pfs
|
||||||
setup_browser_dev
|
setup_browser_dev
|
||||||
|
setup_clipboard
|
||||||
setup_links
|
setup_links
|
||||||
setup_network
|
setup_network
|
||||||
setup_overlayfs
|
setup_overlayfs
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
alias enterVR='js "document.querySelector(\"a-scene\").enterVR()"'
|
|
||||||
alias enterAR='js "document.querySelector(\"a-scene\").enterAR()"'
|
|
||||||
alias exitVR='js "document.querySelector(\"a-scene\").enterVR()"'
|
|
||||||
alias exitAR='js "document.querySelector(\"a-scene\").enterAR()"'
|
|
||||||
|
|
||||||
# (new)user friendlyness
|
# (new)user friendlyness
|
||||||
alias vi='echo -e "HINT: type :q (and press enter) to quit\n[press a key]";read;vi';
|
alias vi='echo -e "HINT: type :q (and press enter) to quit\n[press a key]";read;vi';
|
||||||
alias mg='echo -e "HINT: type Ctrl+c Ctrl-x to quit\n[press a key]";read;mg';
|
alias mg='echo -e "HINT: type Ctrl+c Ctrl-x to quit\n[press a key]";read;mg';
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/js
|
||||||
|
document.querySelector("a-scene").enterAR()
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/js
|
||||||
|
document.querySelector("a-scene").enterVR()
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/js
|
||||||
|
document.querySelector("a-scene").exitAR()
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/js
|
||||||
|
document.querySelector("a-scene").exitVR()
|
|
@ -1,2 +1,2 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
echo hook.d/alert/yo: yo $*
|
echo "$@"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/awk -f
|
#!/usr/bin/awk -f
|
||||||
BEGIN{
|
BEGIN{
|
||||||
print "hook.d/alert/yo.awk: yo " ARGV[1]
|
print( ARGV[0] " " ARGV[1] " " ARGV[2] )
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
#!/bin/js
|
#!/bin/js
|
||||||
str = "hook.d/alert/yo.js yo"+args.slice(1).join(' ')
|
msg = args.join(' ')
|
||||||
alert(str)
|
console.log(msg)
|
||||||
|
//alert(msg)
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
#!/usr/bin/env lua
|
#!/usr/bin/env lua
|
||||||
print("hook.d/alert/yo.lua: yo " .. args[1])
|
local msg = table.concat( arg, " ")
|
||||||
|
print( msg ) -- to stdout
|
||||||
|
--os.execute( "logger '" .. msg .. "'") -- to logs (/var/logs/messages)
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
#!/usr/bin/env micropython
|
#!/usr/bin/env micropython
|
||||||
import sys
|
import sys
|
||||||
print("hook.d/alert/yo.py: "+sys.argv[1])
|
import os
|
||||||
|
msg = sys.argv[0] + ": " + " ".join(sys.argv)
|
||||||
|
|
||||||
|
print(msg) # to stdout
|
||||||
|
#os.system("logger '"+ msg +"'") # to logs (/var/log/messages)
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/js
|
||||||
|
// this allows opening a file upload popup, to upload to the clipboard.
|
||||||
|
// because not all input devices (handcontrols) present copy/paste contextmenus
|
||||||
|
// or file drag/drop functionality
|
||||||
|
//
|
||||||
|
const isoterminal = document.querySelector('[isoterminal]').components.isoterminal
|
||||||
|
const upload = isoterminal.vt100.upload
|
||||||
|
const scene = document.querySelector('a-scene')
|
||||||
|
|
||||||
|
// trigger file input
|
||||||
|
scene.exitVR()
|
||||||
|
upload.click()
|
||||||
|
return "[i] files are uploaded in /mnt/clipboard\n"
|
|
@ -1,9 +1,9 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
infinite inotifyd echo /mnt/root | awk '
|
infinite inotifyd echo /root | awk '
|
||||||
|
|
||||||
# listen for writes to rootdir and send them to DOM
|
# listen for writes to rootdir and send them to DOM
|
||||||
/^[ne] \/mnt\/root index\.html/ { system("cat "$2"/"$3" | grep -vE \"^#!\" > /dev/browser/html") }
|
/^[wne] \/root index\.html/ { system("cat "$2"/"$3" | grep -vE \"^#!\" > /dev/browser/html") }
|
||||||
/^[ne] \/mnt\/root index\.js/ { system("cat "$2"/"$3" | grep -vE \"^#!\" > /dev/browser/js") }
|
/^[wne] \/root index\.js/ { system("cat "$2"/"$3" | grep -vE \"^#!\" > /dev/browser/js") }
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
../../bin/helloworld.awk
|
|
@ -0,0 +1 @@
|
||||||
|
../../bin/helloworld.js
|
|
@ -0,0 +1 @@
|
||||||
|
../../bin/helloworld.lua
|
|
@ -0,0 +1 @@
|
||||||
|
../../bin/helloworld.py
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# usage: hook clipboard foo.mp3 [audio/mpeg]
|
||||||
|
# this forwards the hook to mimetype or filetype
|
||||||
|
source /etc/profile.sh
|
||||||
|
|
||||||
|
file="$1"
|
||||||
|
ext="${file##*.}"
|
||||||
|
mimetype="$2"
|
||||||
|
|
||||||
|
if test -n "$mimetype"; then
|
||||||
|
hook mimetype/"$mimetype" "$file"
|
||||||
|
else
|
||||||
|
hook filetype $ext "$file"
|
||||||
|
fi
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# usage: import-to-aframe <textfile>
|
||||||
|
|
||||||
|
str="$(cat "$1" | sed ':a;N;$!ba;s/\n/\\n/g' )" # escape linebreaks
|
||||||
|
|
||||||
|
echo "<a-text value='${str}' position='-0.4 1.8 -3' grabbable></a-text>" >> /root/index.html
|
|
@ -0,0 +1 @@
|
||||||
|
../../filetype/mp3
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# usage: import-to-aframe <textfile>
|
||||||
|
|
||||||
|
str="$(cat "$1" | sed ':a;N;$!ba;s/\n/\\n/g' )" # escape linebreaks
|
||||||
|
|
||||||
|
echo "<a-text value='${str}' position='-0.4 1.8 -3' grabbable></a-text>" >> /root/index.html
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/sh
|
||||||
|
logger "*TODO*: importing to scene"
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# usage: import-to-aframe <textfile>
|
||||||
|
|
||||||
|
# *FIXME* need consent
|
||||||
|
cat "$1" >> /root/index.html
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/sh
|
||||||
|
source /etc/profile.sh
|
||||||
|
file="$1"
|
||||||
|
|
||||||
|
# naive javascript detector
|
||||||
|
grep '<a-' "$file" &> /dev/null && {
|
||||||
|
cat "$file" | grep -vE '(<script|iframe)' &> "$file".aframe
|
||||||
|
hook mimetype/text/aframe "$file".aframe
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
source /etc/profile.sh
|
||||||
|
file="$1"
|
||||||
|
|
||||||
|
# naive html detector
|
||||||
|
grep -E '(<\/a>|<\/div>)' "$file" &> /dev/null && {
|
||||||
|
hook mimetype/text/html "$file"
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
source /etc/profile.sh
|
||||||
|
file="$1"
|
||||||
|
|
||||||
|
# naive javascript detector
|
||||||
|
grep -E '[a-zA-Z]\(' "$file" &> /dev/null && {
|
||||||
|
hook mimetype/text/javascript "$file"
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# warning: to activate below make this file executable at own risk
|
||||||
|
|
||||||
|
cat $1 | grep -vE "(<script|<iframe)" >> /root/index.html
|
|
@ -0,0 +1 @@
|
||||||
|
plain/import-to-aframe
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# warning: to activate below make this file executable at own risk
|
||||||
|
|
||||||
|
js "$(cat $1)"
|
|
@ -0,0 +1 @@
|
||||||
|
../../filetype/txt
|
|
@ -0,0 +1 @@
|
||||||
|
../../filetype/mp4
|
|
@ -71,6 +71,12 @@ The following files are loaded during boot (via `/etc/profile`)
|
||||||
```javascript
|
```javascript
|
||||||
const term = document.querySelector('[isoterminal]').components.isoterminal.term
|
const term = document.querySelector('[isoterminal]').components.isoterminal.term
|
||||||
term.exec("ls -la")
|
term.exec("ls -la")
|
||||||
|
|
||||||
|
// interact directly with files
|
||||||
|
await term.worker.create_file("hello.txt", term.convert.toUint8Array("hello") )
|
||||||
|
await term.worker.update_file("hello.txt", term.convert.toUint8Array("hi") )
|
||||||
|
await term.worker.append_file("hello.txt", term.convert.toUint8Array("world") )
|
||||||
|
const f = await term.worker.read_file("hello.txt")
|
||||||
```
|
```
|
||||||
|
|
||||||
# Calling javascript from terminal
|
# Calling javascript from terminal
|
||||||
|
@ -82,11 +88,43 @@ Various options:
|
||||||
3. Run `jsh alert hello` in the shell
|
3. Run `jsh alert hello` in the shell
|
||||||
4. Run `jsh` to start an interactive shell
|
4. Run `jsh` to start an interactive shell
|
||||||
|
|
||||||
# Hybrid Terminal/Browser Events
|
# Hooks
|
||||||
|
|
||||||
Events are automatically triggering scripts in `/root/hook.d/{eventname}/*`
|
Hooks are filebased events.
|
||||||
|
Why filebased? Well first, because unixy is sexy.
|
||||||
|
Second: it allows reacting to events in a hackable way via polyglot scripts.
|
||||||
|
|
||||||
> They can be triggered by the following ways
|
> TLDR: events are automatically triggering scripts found in `/root/hook.d/{eventname}/*`
|
||||||
|
|
||||||
|
**OS related hooks**
|
||||||
|
|
||||||
|
| hook location | when is this hook called? |
|
||||||
|
|-------------------------|-------------------------------------------------------|
|
||||||
|
| hook.d/wakeup/* | restoring xrsh session from cache |
|
||||||
|
| hook.d/save/* | saving xrsh session to cache |
|
||||||
|
| hook.d/alert/* | when 'alert'-function is used in shell |
|
||||||
|
| hook.d/prompt/* | when 'prompt'-function is used in shell |
|
||||||
|
| hook.d/confirm/* | when 'confirm'-function is used in shell |
|
||||||
|
|
||||||
|
**Clipboard related hooks**
|
||||||
|
|
||||||
|
| hook.d/clipboard/* | user copy-pastes clipboard or (drops) file into scene |
|
||||||
|
| hook.d/mimetype/* | clipboard activity (hook.d/clipboard/forwarder) |
|
||||||
|
| hook.d/filetype/* | clipboard activity (hook.d/clipboard/forwarder) |
|
||||||
|
|
||||||
|
**XR related hooks**
|
||||||
|
|
||||||
|
| hook location | when is this hook called? |
|
||||||
|
|-------------------------|-------------------------------------------------------|
|
||||||
|
| hook.d/exit-vr/* | user exits immersive WebXR [VR] mode |
|
||||||
|
| hook.d/enter-vr/* | user enters immersive WebXR [VR] mode |
|
||||||
|
| hook.d/exit-ar/* | user exits immersive WebXR [AR] mode |
|
||||||
|
| hook.d/enter-ar/* | user enters immersive WebXR [AR] mode |
|
||||||
|
|
||||||
|
> How to trigger them?
|
||||||
|
|
||||||
|
Well the isoterminal-AFRAME component triggers them automatically for you.
|
||||||
|
But you can do it manually too:
|
||||||
|
|
||||||
1. from shellscript: `hook myevent` (will trigger **executable** files in /root/hook.d/myevent)
|
1. from shellscript: `hook myevent` (will trigger **executable** files in /root/hook.d/myevent)
|
||||||
2. from javascript: `isoterminal.exec("hook myevent")` (idem)
|
2. from javascript: `isoterminal.exec("hook myevent")` (idem)
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue