Haiku scripting

The script just converts in %d %h %m the amount of time between the very current time and the start of the event, so it converts a number to a string ; probably adding a leading 0 would fix that, but I don’t like it so I didn’t try it

Edit: or adding a leading space, it’s still unpleasant, but lesser than with a zero

Basically those are just triangles, rotated from the center and scaled/faded, but yab is able to draw arcs too,a so it could draw something similar to the disk usage app

So it takes ~ 5 sec to query 7 events, extract the attributes, do some maths, create some SVG icons (at the first run ) and draw the “clock”

7 Likes

How you make that columnbox, any recommendation?

Edti: Oh ok, it was with yab i see, i was thinking was with c++

1 Like

You are right, no “real” programming is involved in this script :joy:

But this is quite cool, you can have a spreadsheet-like interface with sorting with a little effort

2 Likes

in C++ you can use BColumnListView, it is very similar

1 Like

Hi, there is a snippet, I think it could be useful if you want to get the color of the current Desktop for your script

message /boot/home/config/settings/system/app_server/workspaces | awk '/color/ {print substr($3,15,2)substr($3,13,2)substr($3,11,2)}' | sed -n `hey Tracker get Workspaces of Window 0 | awk '/result/ {printf 1+log(sqrt($4^2))/log(2)}'`p

the result is expressed in hex, easy to convert to dec; in case the window is shown in all workspaces, you’ll get only the first one, substite “Tracker” and the window ID with your preferred app

2 Likes

Hello everyone,

Here are 2 easy scripts to create a new or install existing http website on apache and nginx.
I’ll publish https scripts for both later (time to adapt them to Haiku).

Apache :

#!/bin/bash
clear
echo "-----------------------------------------------------"
echo "Welcome to website installation with apache for Haiku"
echo "-----------------------------------------------------"
echo "We set up a few things, please wait !"
sleep 2

mkdir /system/var/logs
pkgman install apache -y

sed -i 's/#ServerName www.example.com:80/ServerName localhost:80/' /system/settings/apache/httpd.conf
sed -i 's/#Include \/boot\/system\/settings\/apache\/extra\/httpd-vhosts.conf/Include \/boot\/system\/settings\/apache\/extra\/httpd-vhosts.conf/' /system/settings/apache/httpd.conf

clear
echo "--------------------------------------"
echo "What will be the URL of your website ?" 
echo "(example : www.user-assistance.lan)"
read d
i=0
while [ $i -lt 4 ]; do
        if [ -d "/system/var/www/$d" ]; then
		   echo "-----------------------------"
           echo "This domain is already taken"
           echo "Please choose another one"
           i=$((i+1))
           read d
        else
           i=$((i+25))
        fi
done
if [ $i -eq 4 ]; then
      exit 0
fi

clear
echo "--------------------------------------------------"
echo "Do you want to install [i] an existing website, or" 
echo "Do you want to create [n] a new website ?"
read instn
case $instn in
    i)
        clear
        echo "------------------------------------------------------------------------"
        echo "Please indicate the absolute path of the DocumentRoot of your website"
        echo "(folder containing all your website, including index)"
        echo "------------------------------------------------------------------------"
        echo "(Please do not end it with /)"
		echo "(Example : /boot/home/Desktop/mysuperwebsite)"
        read pathsite
        mkdir -p /system/var/www/$d/logs
        cp $pathsite/* /system/var/www/$d
    ;;
    n)
        mkdir -p /system/var/www/$d/logs
        clear
        echo "-------------------------------------------------"
        echo "Please enter a few words for your index.html page"
        echo "(Example : Welcome to $d)"
        read l
        echo "$l" > /system/var/www/$d/index.html
        clear
    ;;
esac

# Vhost setting in httpd-vhosts.conf
printf "\n" >> /system/settings/apache/extra/httpd-vhosts.conf
echo "#### VHOST $d ####" >> /system/settings/apache/extra/httpd-vhosts.conf
echo "<VirtualHost *:80>
   ServerName $d
   DocumentRoot /system/var/www/$d
   ErrorLog /system/var/www/$d/logs/error.log
   CustomLog /system/var/www/$d/logs/access.log combined
   <Directory /system/var/www/$d>
      Require all granted
   </Directory>
</VirtualHost>" >> /system/settings/apache/extra/httpd-vhosts.conf

# Get local IP of your Haiku, put it in hosts file
echo "------------------------------------------------------------------------"
echo "Here comes local IP addresses"
sleep 2
echo "------------------------------------------------------------------------"
route | grep HL | grep /dev
echo "------------------------------------------------------------------------"
echo "Can you indicate me your IP address"
echo "(write it, example : 192.168.0.25)"
read ipaddr

# Record to hosts file
echo "$ipaddr	$d" >> /system/settings/network/hosts

# restart httpd
kill httpd
sleep 2
/bin/httpd

# End resume
clear
echo "------------------------------------------------------------------------"
echo "Remember"
echo "-----you've created a DocumentRoot /system/var/www/$d"
echo "-----you activated a vhost /system/settings/apache/extra/httpd-vhosts.conf"
echo "-----once a DNS record will be done on other machines on the LAN, your website will be accessible on"
echo "-----http://$d" 
echo "------------------------------------------------------------------------"
echo "Hit any key to leave"
read quit

Nginx :

#!/bin/bash
clear
echo "------------------------------------------------------------------------"
echo "Welcome to website installation with Nginx for Haiku"
echo "------------------------------------------------------------------------"
echo "We set up a few things, please wait"
sleep 2
pkgman install nginx -y
clear
echo "--------------------------------------"
echo "What will be the URL of your website ?" 
echo "(example : www.user-assistance.lan)"
read d
i=0
while [ $i -lt 4 ]; do
    domacou=`cat /system/settings/nginx/nginx.conf | grep $d | wc -l`
    if [ "$domacou" == "1" ]; then
	    echo "------------------------------------------------------------------------"
        echo "This domain is already taken"
        echo "Please choose another one"
        i=$((i+1))
        read d
    else
        i=$((i+25))
    fi
done
if [ $i -eq 4 ]; then
    exit 0
fi 

clear
echo "--------------------------------------------------"
echo "Do you want to install [i] an existing website, or" 
echo "Do you want to create [n] a new website ?"
read instn
case $instn in
    i)
        clear
        echo "------------------------------------------------------------------------"
        echo "Please indicate the absolute path of the DocumentRoot of your website"
        echo "(folder containing all your website, including index)"
        echo "------------------------------------------------------------------------"
        echo "(Please do not end it with /)"
		echo "(Example : /boot/home/Desktop/mysuperwebsite)"
        read pathsite
        mkdir /system/var/www/$d
        cp $pathsite/* /system/var/www/$d
    ;;
    n)
        mkdir /system/var/www/$d
        clear
        echo "------------------------------------------------------------------------"
        echo "Please enter a few words for your index.html page"
        echo "(Example : Welcome to $d)"
        read l
        echo "$l" > /system/var/www/$d/index.html
        clear
    ;;
esac

# Vhost setting in httpd-vhosts.conf
sed '$d' /system/settings/nginx/nginx.conf > /tmp/temp && mv /tmp/temp /system/settings/nginx/nginx.conf
printf "\n" >> /system/settings/nginx/nginx.conf
echo "#### VHOST $d ####" >> /system/settings/nginx/nginx.conf
echo "server {" >> /system/settings/nginx/nginx.conf
echo "  listen 80;" >> /system/settings/nginx/nginx.conf
echo "  server_name $d;" >> /system/settings/nginx/nginx.conf
echo '  location / {' >> /system/settings/nginx/nginx.conf
echo "      root /system/var/www/$d;" >> /system/settings/nginx/nginx.conf
echo "      index index.html index.htm;" >> /system/settings/nginx/nginx.conf
echo "  }" >> /system/settings/nginx/nginx.conf
echo "}" >> /system/settings/nginx/nginx.conf
printf "\n" >> /system/settings/nginx/nginx.conf
echo "}" >> /system/settings/nginx/nginx.conf

# Get local IP of your Haiku, put it in hosts file
echo "------------------------------------------------------------------------"
echo "Here comes local IP addresses"
sleep 2
echo "------------------------------------------------------------------------"
route | grep HL | grep /dev
echo "------------------------------------------------------------------------"
echo "Can you indicate me your IP address"
echo "(write it, example : 192.168.0.25)"
read ipaddr

# Record to hosts file
echo "$ipaddr	$d" >> /system/settings/network/hosts

# restart Nginx
kill nginx 
sleep 2
/bin/nginx

# End resume
clear
echo "------------------------------------------------------------------------"
echo "Remember"
echo "-----you've created a DocumentRoot /system/var/www/$d"
echo "-----you activated a vhost /system/settings/nginx/nginx.conf"
echo "-----once a DNS record will be done on other machines on the LAN, your website will be accessible on"
echo "-----http://$d"
echo "------------------------------------------------------------------------"
echo "Hit any key to leave"
read quit
2 Likes

This yab script is almost done, it needs to be commented out more and the replicant emulation is done brutally by constantly deactivating the window so that it never brings to front, as the B_AVOID_FRONT flag doesn’t seem to do anything.

5 Likes

I just designed the prototype of a GUI for a hypothetical YAB script that would bmessage the app_server, or perhaps Thememanager, to set up a dark/light theme with accents but probably this is not possible, but I prefer to ask the great wisemen that watch over this forum before to throw out everything of the window
https://youtube.com/shorts/cv0SgNp4BGM

3 Likes

This link is addictive!
Spent 30min on it!
Thanks for making me laugh! :rofl:

1 Like

Not my original intent but I’m glad you enjoyed :stuck_out_tongue_winking_eye:

2 Likes

A tiny Bash script that shows the weather using wttr.in (https://github.com/chubin/wtr.in) as a one-liner in the title of a terminal, the script is brought to you without any guarantee since it is written sloppy

#! /bin/sh

prev_title="HWttr"

# define your location, or you are going to be geolocalized

curr_loc=""

Terminal -t "${prev_title}" &

# cool down

sleep 0.1

# set the window as wide as the Desktop, and put it on the bottom of the screen

hey -o Terminal set Frame of Window "${prev_title}" to `hey Tracker get Frame of Window 0 | awk -F'[,()]' '/result/ {printf "BRect[0,%s,%s,%s]",$7+6,$6+0,$7+6}'`

# change the window's flags

#	Flags:
#	normal window	1572864
#	not-movable		1
#	not-resizable	2
#	not-closable	32
#	not-zoomable	64
#	avoid-front		128
#	avoid-focus		8192
#	not-minimizable	16384

hey -o Terminal set Flags of Window "${prev_title}" to $((1572864+1+2+32+64+128+16384))

# set the window to float above the other windows

hey -o Terminal set Feel of Window "${prev_title}" to 6

# a ugly loop

while [ true ]

do

# get the current weather, you can set the verbosity of the line changing format from 1 to 4, of set your custom format, as in the example below

# ?format="%l:+%c+%t+(%f)+%w+%h+%p+%P" , check https://github.com/chubin/wttr.in

title="`curl wttr.in/${curr_loc}?format=2` ⏲ `date +%R`"

# let's add the fetch time too

# change the window's title with the current weather

hey -o Terminal set Title of Window "${prev_title}" to "${title}"

prev_title="${title}"

# wait a hour before to fetch the data again

sleep 60m

# if the window doesn't exist, i.e. you closed it with alt+q, the script exits the loop

hey -o Terminal getsuites of Window "${prev_title}"

[ $? -eq 1 ] && exit

done
2 Likes

This isn’t really Haiku specific, but I wanted to share it nonetheless.
[Edited to include madmax’ suggestions from a comment below.]

#!/bin/sh

# A script to replace a sentence in all files in this and all
# sub-folders (excluding .git folders) with another sentence.
# Old and new sentences are optional parameters. Without parameters
# you get asked for the old and new strings.

OLDFORMAT='\033[37;41m'
NEWFORMAT='\033[37;42m'
NOFORMAT='\033[0m'

old=""
new=""
files=""

if [[ $# -eq 0 ]] ; then
	while [[ "$old" == "" ]] ; do
		read -p "Enter old string: " old
	done
	read -p "Enter new string: " new
else
	old="${1}"
	new="${2}"
fi

files=$(grep -FIrl "$old" --exclude-dir=.git)

if [[ "$files" == "" ]] ; then
	echo -e "Didn't find any: ${OLDFORMAT}$old${NOFORMAT}"
	exit 1
fi

echo
if [[ "$new" == "" ]] ; then
	echo "Removing:"
	echo -e "\t${OLDFORMAT}$old${NOFORMAT}"
else
	echo "Replacing:"
	echo -e "\t${OLDFORMAT}$old${NOFORMAT}"
	echo "with:"
	echo -e "\t${NEWFORMAT}$new${NOFORMAT}"
fi
echo
echo "in these files:"
echo
echo -e "$files"
echo

read -p "Do the replacement? (y)es: " answer
if [[ "$answer" != y* ]] || [[ "$answer" == "" ]] ; then
	echo "Abort!"
	exit 1
fi

# Escape 'special' characters in old and new string
old=$(printf '%s\n' "$old" | sed -e 's/[]\/$*.^[]/\\&/g');
new=$(printf '%s\n' "$new" | sed -e 's/[\/&]/\\&/g')

echo "$files" | xargs --delimiter='\n' sed -i "s/$old/$new/g"

You’ll get asked for confirmation before the replacing. Anything else but “y” or “yes” (or anything not starting with a “y”, actually) aborts.

This is an example output:

terminal

[I’m not a master scripter and appreciate improvements.]

1 Like

Since it quits silently in case of abortion or success, I would add at exit a counter to say how many files were modified or the number of occurrences replaced. But a simple “Done” / “Aborted” could also do the trick.

As it shows the files containing the old string, and answering “yes” when asked for confirmation, I think that the prompt returning signals the replacing has finished.
I’m not sure showing the number of replaced strings is a useful info. Before I call this replacement script, I should be very sure that all occurrances of the old string are OK to be replaced. Either with the TextSearch Tracker add-on or a quick “grep -R”.

I’m sure there are many things that could possibly be added, everyone feel free to explore and create your own derivate that suits your needs. :slight_smile:
With improvements, I rather meant hidden bugs or stylistic no-nos.

It could be if you haf used #!sh as the shebang : )

It depends on what you mean by hidden bugs, and I’ve not tested the Haiku versions of the commands for its idiosyncrasies, so not sure if all of them apply.

  • Say you want to change ‘home/settings’ for ‘system/settings’. sed -i "s/$old/$new/g" breaks due to the ‘/’. You’d have to use ${old//\//\\/} (if that’s not a bashism). You’d also have to escape the backslash, probably. And anything else with a special meaning, like dot, asterisk, bracket… Or at least be aware that you can’t use them.
  • grep returns the list of files separated by a newline. So if any of your files have a name with a newline you are out of luck. This is unusual and you probably have lots of other problems, so this one may not be that important. You can make grep return an unambiguous list with the -Z option, that instructs it to use a null byte as separator, but then you can’t capture it in files, you’d have to directly feed that to xargs -0 or transform it.
  • echo ... | xargs cmd does not only have problems with newlines (and backslashes?) in names, but also with the more common spaces, as each word will be a different parameter for cmd. Tell xargs you are using newlines with --delimiter='\n'.
1 Like

Thanks for those pointers, @madmax!

And this is why sed and I will never be friends… :smile:
I found a page related to this on StackOverflow and incorporated their escape lines into my above script:

# Escape 'special' characters in old and new string
old=$(printf '%s\n' "$old" | sed -e 's/[]\/$*.^[]/\\&/g');
new=$(printf '%s\n' "$new" | sed -e 's/[\/&]/\\&/g')

Hopefully it covers most common issues. I did hop on one leg under a full moon while copy and pasting that incantation… :mage:

I also added your suggestion to set xargs’ delimiter to deal with spaces etc. in filenames, but chose to ignore possible pitfalls with filenames that include newlines. Too rare an animal to find in the wild, I think.

Thanks a lot!

Hi guys, I need some help
After all these years I’m still struggling to understand fully hey, I’m currently having ‘fun’ writing a shell script that moves around LaunchBox (not that around, just near the DeskBar) and in some cases I’d like to change its orientation… looking at Launchbox code I see that there the definition of ‘tgll’ as MSG_TOGGLE_LAYOUT, and later on the code

[...]
void
PadView::MessageReceived(BMessage* message)
{
	switch (message->what) {
		case MSG_TOGGLE_LAYOUT:
			if (fButtonLayout->Orientation() == B_HORIZONTAL) {
				fButtonLayout->SetInsets(2, 7, 2, 2);
				fButtonLayout->SetOrientation(B_VERTICAL);
			} else {
				fButtonLayout->SetInsets(7, 2, 2, 2);
				fButtonLayout->SetOrientation(B_HORIZONTAL);
			}
			break;
[...]

I tried with a random
hey LaunchBox ‘tgll’
Or
hey LaunchBox let Window 0 do ‘tgll’
Both seem received and OK replied, but nothing happens.

I admit my ignorance, there is a kind person that could help me to understand how to message to an app?

1 Like