Haiku scripting

This thread is meant to share useful scripts between users

2 Likes

winpwnr.sh
winpwnr.sh is a one-liner Haikus’ hey front-end with the only intent to domate windows

#! /bin/sh

Usage()
{
echo "usage: ${script_name} -option <value>
	-a	select the application by name
	
	-l	list windows for the selected application
	
	-s	select application's window by ID number or title

	-d	avoid to overlap the Deskbar

	-t	change the title of the selected window 
	
	-f	force fullscreen for the selected window, no value is needed
	
	-w	show the selected window on {x} workspace(s),
			you can set multiple values separated by any character, like
			\"1,2,4,5\" or \"5.6.1\", use \"all\" to show it in every workspace
			
	-p	move the selected window by x,y pixels (relative)
			
	-P	move the selected window to x,y (absolute) position
			
	-L	change the LOOK of the selected window:
			- b OR bordered
			- n OR no-border
			- t OR titled
			- d OR document
			- m OR modal
			- f OR floating
			
	-F	change the FEEL of the selected window:
			- n OR normal
			- ms OR modal-subset
			- mp OR modal-app
			- ml OR modal-all
			- fs OR floating-subset
			- fp OR floating-app
			- fl OR floating-all
			
	-G	change the FLAGS of the selected window, multiple valuese are accepted separated by commas
			- nm OR not-movable
			- nr OR not-resizable
			- nh OR not-h-resizable
			- nv OR not-v-resizable
			- fs OR accept-first-click
			- nc OR not-closable
			- nz OR not-zoomable
			- af OR avoid-front
			- nw OR no-workspace-activation
			- as OR avoid-focus
			- nb OR not-minimizable
			- na OR not_anchored
			- sp OR same-position
			- ce OR close-on-escape
			
	-M	minimize the selected window (1, t, true, on, y, yes / 0, f, false, off, n, no / toggle)
	
	-A	active the selected window (1, t, true, on, y, yes / 0, f, false, off, n, no / toggle)
	
	-m	move the selected window against the edges and corners of the screen:
		
		7	8	9		ul	u	ur		up-left		up		up-right
		
		4	5	6	OR	l	c	r	OR	left		center		right
		
		1	2	3		dl	d	dr		down-left	down		down-right
			
	-H	as the -m option but the selected window will be moved to the edges resized to half the screen size, a quarter of the screen size to the corners
	
	-r	resize the frame of the selected window to width,height, centered with respect to the original window and avoiding going out of bounds"
	>&2
exit
}

CheckArgs()
{
if [ $(echo -n "$1" | wc -c) -eq 2 ] && [ $(echo -n "$1" | awk '/-/{print}') ]
then
	shift $((OPTIND-1))
	return 1
fi	
}

SetWorkspace ()
{
[ "$1" != "all" ] && hey -o "${app_name}" set Workspaces of Window "${win_ID}" to `echo -n $1 | awk '{for(i=1;i<=NF;i++) print ($i-1)}' FS="[^0-9]" | sort -u | awk '{val+=2^($0)} END {print val}'` || hey -o "${app_name}" set Workspaces of Window "${win_ID}" to -1
}

EnlistWindows()
{
for (( i=0;i<=`echo $(hey "${app_name}" Count of Window | awk '/result/{print $4}') - 1 | bc`;i++ )); do echo -n "$i) ";hey "${app_name}" get Title of Window "$i" | awk '/result/{print $4}' FS="\""; done
}

ChangeTitle ()
{
hey -o "${app_name}" set Title of Window "${win_ID}" TO "$1"
}

ResizeFrame()
{
PeekDesktop
hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[\
$((echo -n "$1,"; hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}'; echo -n ${dt_frame}) | awk '{\
if ($1<$9) {x_pos=int($3+(($5-$3-$1)/2)); wx_pos=x_pos+$1; if (x_pos<0) {wx_pos-=x_pos;x_pos=0;};if (wx_pos>$9){delta=(wx_pos-$9);wx_pos-=delta;x_pos-=delta;}}\
else {x_pos=0;wx_pos=$9;};\
if ($2<$10) {y_pos=int($4+(($6-$4-$2)/2)); wy_pos=y_pos+$2; if (y_pos<0) {wy_pos-=y_pos;y_pos=0;};if (wy_pos>$10){delta=(wy_pos-$10);wy_pos-=delta;y_pos-=delta;}}\
else {y_pos=0;wy_pos=$10;};\
print x_pos,y_pos,wx_pos,wy_pos}' FS="," OFS=",")]
}
PlaceOnEdges()
{
PeekDesktop
case $1 in
	7|ul|up-left)
		hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print $5,$6,$5+($3-$1),$6+($4-$2)}' FS="," OFS=",")]
		;;		
	8|u|up)
		hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print int(($7-($3-$1))/2),$6,int(($7+($3-$1))/2),$6+($4-$2)}' FS="," OFS=",")]
		;;		
	9|ur|up-right)
		hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print ($7-($3-$1)),$6,$7,$6+($4-$2)}' FS="," OFS=",")]
		;;		
	4|l|left)
		hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print $5,int(($8-($4-$2))/2),$5+($3-$1),int(($8+($4-$2))/2)}' FS="," OFS=",")]
		;;
	5|c|center)
		hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print int(($7-($3-$1))/2),int(($8-($4-$2))/2),int(($7+($3-$1))/2),int(($8+($4-$2))/2)}' FS="," OFS=",")]
		;;		
	6|r|right)
		hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print ($7-($3-$1)),int(($8-($4-$2))/2),$7,int(($8+($4-$2))/2)}' FS="," OFS=",")]
		;;	
	1|dl|down-left)
		hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print $5,($8-($4-$2)),$5+($3-$1),$8}' FS="," OFS=",")]
		;;
	2|d|down)
		hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print ($7-($3-$1))/2,($8-($4-$2)),int(($7+($3-$1))/2),$8}' FS="," OFS=",")]
		;;
	3|dr|down-right) # lower right corner. half screen size
		hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$((hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${dt_frame}) | awk '{print ($7-($3-$1)),($8-($4-$2)),$7,$8}' FS="," OFS=",")]
		;;
	*)
		Usage
	;;
esac
}
SplitOnEdges()
{
PeekDesktop
case $1 in
	7|ul|up-left) # upper left corner, 1/4 screen size
	hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print $1,$2,int($3/2),int($4/2)}' FS="," OFS=",")]
		;;		
	8|u|up) # upper half screen height
	hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print $1,$2,$3,int($4/2)}' FS="," OFS=",")]
		;;		
	9|ur|up-right) # upper right corner, 1/4 screen size
	hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print int($3/2),$2,$3,int($4/2)}' FS="," OFS=",")]
		;;		
	4|l|left) # left half screen width
	hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print $1,$2,int($3/2),$4}' FS="," OFS=",")]
		;;
	5|c|center) # middle screen, half screen size	
	hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print int($3/4),int($4/4),int($3*3/4),int($4*3/4)}' FS="," OFS=",")]
		;;		
	6|r|right) # right half screen width
	hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print int($3/2),$2,$3,$4}' FS="," OFS=",")]
		;;	
	1|dl|down-left) # lower left corner. half screen size
	hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print $1,int($4/2),int($3/2),$4}' FS="," OFS=",")]
		;;
	2|d|down) # lower half screen height
	hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print $1,int($4/2),$3,$4}' FS="," OFS=",")]
		;;
	3|dr|down-right) # lower right corner. half screen size
	hey -o "${app_name}" set Frame of Window "${win_ID}" TO BRect[$(echo ${dt_frame} | awk '{print int($3/2),int($4/2),$3,$4}' FS="," OFS=",")]
		;;
	*)
		Usage
	;;
esac
}
FullScreen()
{
PeekDesktop
hey -o "${app_name}" set Frame of Window "${win_ID}" to BRect[${dt_frame}]
}
ChangeLook()
{
case $1 in
	b|bordered)
		hey -o "${app_name}" set Look of Window "${win_ID}" to 20
		;;
	n|no-border)
		hey -o "${app_name}" set Look of Window "${win_ID}" to 19
		;;
	t|titled)
		hey -o "${app_name}" set Look of Window "${win_ID}" to 1
		;;
	d|document)
		hey -o "${app_name}" set Look of Window "${win_ID}" to 11
		;;
	m|modal)
		hey -o "${app_name}" set Look of Window "${win_ID}" to 3
		;;
	f|floating)
		hey -o "${app_name}" set Look of Window "${win_ID}" to 7
		;;
	*)
		Usage
		;;
esac
}
ChangeFeel()
{
case $1 in
	n|normal)
		hey -o "${app_name}" set Feel of Window "${win_ID}" to 0
		;;
	ms|modal-subset)
		hey -o "${app_name}" set Feel of Window "${win_ID}" to 2
		;;
	mp|modal-app)
		hey -o "${app_name}" set Feel of Window "${win_ID}" to 1
		;;
	ml|modal-all)
		hey -o "${app_name}" set Feel of Window "${win_ID}" to 3
		;;
	fs|floating-subset)
		hey -o "${app_name}" set Feel of Window "${win_ID}" to 5
		;;
	fp|floating-app)
		hey -o "${app_name}" set Feel of Window "${win_ID}" to 4
		;;
	fl|floating-all)
		hey -o "${app_name}" set Feel of Window "${win_ID}" to 6
		;;
	*)
		Usage
		;;
esac
}
SumFlags()
{
case $1 in
	nm|not-movable)
		let flags+=1
		;;
	nr|not-resizable)
		let flags+=2
		;;
	nh|not-h-resizable)
		let flags+=4
		;;
	nv|not-v-resizable)
		let flags+=8
		;;
	fs|accept-first-click)
		let flags+=16
		;;
	nc|not-closable)
		let flags+=32
		;;
	nz|not-zoomable)
		let flags+=64
		;;
	af|avoid-front)
		let flags+=128
		;;
	nw|no-workspace-activation)
		let flags+=256
		;;
	as|avoid-focus)
		let flags+=8192
		;;
	nb|not-minimizable)
		let flags+=16384
		;;
	na|not_anchored)
		let flags+=131072
		;;
	sp|same-position)
		let flags+=2097152
		;;
	ce|close-on-escape)
		let flags+=8388608
		;;
	r| reset)
		flags=1572864
		;;
	*)
		Usage
		;;
esac
}
ChangeFlags()
{
flags=1572864
while read line; do
SumFlags ${line}
done <<< $( echo $1 | tr "," "\\n" )
hey -o "${app_name}" set Flags of Window "${win_ID}" to ${flags} 
}
ToggleActive()
{
case $1 in
	1|t|true|on|y|yes)
		hey -o "${app_name}" set Active of Window "${win_ID}" to true
		;;
	0|f|false|off|n|no)
		hey -o "${app_name}" set Active of Window "${win_ID}" to false
		;;
	toggle)
		active=`hey -o "${app_name}" get Active of Window "${win_ID}"`
		[ "${active}" == "true" ] && ToggleActive 0 || ToggleActive 1
		;;
	*)
		Usage
		;;
esac
}
ToggleMinimize()
{
case $1 in
	1|t|true|on|y|yes)
		hey -o "${app_name}" set Minimize of Window "${win_ID}" to true
		;;
	0|f|false|off|n|no)
		hey -o "${app_name}" set Minimize of Window "${win_ID}" to false
		;;
	toggle)
		minimized=`hey -o "${app_name}" get Minimize of Window "${win_ID}"`
		[ "${minimized}" == "true" ] && ToggleMinimize 0 || ToggleMinimize 1
		;;
	*)
		Usage
		;;
esac
}
AbsPositionIt ()
{
hey -o "${app_name}" let Window "${win_ID}" do MoveTo BPoint[$1]
}
RelPositionIt ()
{
hey -o "${app_name}" let Window "${win_ID}" do MoveBy BPoint[$1]
#\$((echo -n "$1,"; hey "${app_name}" get Frame of Window "${win_ID}" | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s",$0}') | awk '{print $3+$1,$4+$2}' FS="," OFS=",")]
}
PeekDesktop ()
{
dt_frame=$((hey Tracker get Frame of Window 0 | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s,",$0}' ; echo -n ${db_frame})  | awk '{\
if (($5!=0) && ($7==$3 )) {print "0","0",$5,$4};\
if (($5==0) && ($7!=$3)) {print $7,"0",$3,$4};\
if (($7-$5)==($3-$1)) {if ($6!=0) {print "0","0",$3, $6}\
else {print "0",$8,$3,$4}}\
}' FS="," OFS=",")
}
PeekDeskbar ()
{
db_frame=$(hey Deskbar get Frame of Window 0 | awk '/result/{sub(/^.*\(/,"");sub(/\)/,"");gsub(" ","");printf "%s",$0}')
}
###############
# main script #
###############
script_name="$(basename ${0})"
db_frame="0,0,0,0"
if [ $# -ne 0 ]
then
	while getopts "a:dhlfs:t:w:L:F:p:P:m:H:r:M:A:G:" script_opt
	do
		case ${script_opt} in
		a)
			app_name="$OPTARG"
			;;
		l)
			[ -n "${app_name}" ] && EnlistWindows
			exit
			;;
		s)
			[ -n "${app_name}" ] && win_ID="$OPTARG" || Usage
			;;
		
		P)
			if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
				then
					CheckArgs "$OPTARG"
					[ $? -ne 1 ] &&	AbsPositionIt "$OPTARG"
				else
					Usage
			fi
			;;
		p)
			if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
				then
					CheckArgs "$OPTARG"
					[ $? -ne 1 ] &&	RelPositionIt "$OPTARG"
				else
					Usage
			fi
			;;
			
		d)
			if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
				then
					PeekDeskbar
				else
					Usage
			fi
			;;
		m)
			if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
			then
				CheckArgs "$OPTARG"
				[ $? -ne 1 ] &&	PlaceOnEdges "$OPTARG"
			else
				Usage
			fi
			;;	
		H)
			if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
			then
				CheckArgs "$OPTARG"
				[ $? -ne 1 ] &&	SplitOnEdges "$OPTARG"
			else
				Usage
			fi
			;;
		f)
			if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
			then
				FullScreen
			else
				Usage
			fi
			;;
		t)
			if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
			then
				CheckArgs "$OPTARG"
				[ $? -ne 1 ] &&	ChangeTitle "$OPTARG"
			else
				Usage
			fi
			;;
		w)
			if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
			then
				CheckArgs "$OPTARG"
				[ $? -ne 1 ] &&	SetWorkspace "$OPTARG"
			else
				Usage
			fi
			;;
		r)
			if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
			then
				CheckArgs "$OPTARG"
				[ $? -ne 1 ] &&	ResizeFrame "$OPTARG"
			else
				Usage
			fi
			;;
		L)
			if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
			then
				CheckArgs "$OPTARG"
				[ $? -ne 1 ] &&	ChangeLook "$OPTARG"
			else
				Usage
			fi
			;;
		F)
			if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
			then
				CheckArgs "$OPTARG"
				[ $? -ne 1 ] &&	ChangeFeel "$OPTARG"
			else
				Usage
			fi
			;;
		G)
			if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
			then
				CheckArgs "$OPTARG"
				[ $? -ne 1 ] &&	ChangeFlags "$OPTARG"
			else
				Usage
			fi
			;;
		A)
			if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
			then
				CheckArgs "$OPTARG"
				[ $? -ne 1 ] &&	ToggleActive "$OPTARG"
			else
				Usage
			fi
			;;
		M)
			if [ -n "${app_name}" ] && [ -n "${win_ID}" ]
			then
				CheckArgs "$OPTARG"
				[ $? -ne 1 ] &&	ToggleMinimize "$OPTARG"
			else
				Usage
			fi
			;;
		h|*)
			Usage
			;;
		esac
	done
else
	Usage
fi
exit

Pratical example
winpwnr.sh -a Terminal -s 0 -d -H up
move the first opened Terminal window to the upper screen edge occupying half screen vertically, full screen width but avoiding to overlap the Deskbar

winpwnr.sh -a Pe -s Snippets -r 400,400 -m left -w all - G not-closable,not-movable,not-resizable,not-zoomable,not-minimizable -L bordered
Pe’s snippets window is resized to a 400 px squared frame, moved against left screen edge, freeze its position, removing window title tab, shown on all workspaces

I think this can be useful running in a boot script

2 Likes

Another example how I use the script above

Forked Popup/Quake style terminal using the hey command
to use winpwnr.sh, the Terminal will fit the upper half of screen, while not active will be moved upward showing only a thin area, click on that area to make the window active again and bring back the Terminal

#!/bin/sh

### the unique window title prefix for our terminal session
terminalKeyword="QuakeTerm"

### optionally set the location of a custom terminal profile to be used
### it must contain whatever is used as the terminalKeyword at the beginning of the "Window title"
### for example:    "Window title" , "QuakeTerm %i: %t"
# terminalProfile="/boot/home/config/non-packaged/apps/MyCustomTerminal"

### watch and minimize the window even if it was activated by Deskbar/twitcher/....
### otherwise only auto-hide if it's been activated by this script
### comment out the line to disable
continuousWatch=1

### how frequently should we check the status of the window
### lower numbers give faster response and can be decimal numbers like 0.5,1.5,2.2,...
watcherSleepTime=1

move_by=$(hey Tracker get Frame of Window 0 | awk '/result/{sub(/...$/,"");print ($7+1)/2-10}')

### function to find the process ID of our custom terminal session
function findTerminalSession() {
	QTERMPID=-99
	for i in `roster | fgrep /apps/Terminal | awk '{ print $1 }'`;do
		title=`hey -o $i get Title of Window 0 | grep "^${terminalKeyword}"`
		if [ -n "${title}" ];then
			QTERMPID=$i
			break
		fi
	done
}


### initial check to see if we're already running
findTerminalSession

if [ ${QTERMPID} -lt 0 ];then
	### no existing terminal session, start a new one

	if [ -n "${terminalProfile}" ];then
		open "${terminalProfile}"
	else
		/boot/system/apps/Terminal -t "${terminalKeyword}" &
	fi

	### loop a few times to give the terminal process time to start before giving up
	for i in {1..6};do
		findTerminalSession
		if [ ${QTERMPID} -gt 0 ];then
			break;
		elif [ ${i} -eq 6 ];then
			### last time through the loop and we haven't found our terminal
			alert --stop "Error finding custom Terminal process"
			exit 1
		else
			sleep 1
		fi
	done

	### disable the fullscreen button in the tabbar
	hey ${QTERMPID} set Enabled of View 1 of View 1 of Window 0 to false

	### resize and then hide the menubar
	### extract our current BRect(left,top,right,bottom) frame and replace the fourth number with 0.0
	menuFrame=`hey ${QTERMPID} get Frame of View 0 of Window 0 | grep -o 'BRect(.*)$' | sed 's/[0-9]\+.[0-9]\+/0.0/4'`
	hey ${QTERMPID} set Frame of View 0 of Window 0 to "${menuFrame}"
	hey ${QTERMPID} set Hidden of View 0 of Window 0 to true

	### resize the tabview to take up the empty menubar space
	### extract our current BRect(left,top,right,bottom) frame and replace the second number with 0.0
	tabFrame=`hey ${QTERMPID} get Frame of View 1 of Window 0 | grep -o 'BRect(.*)$' | sed 's/[0-9]\+.[0-9]\+/0.0/2'`
	hey ${QTERMPID} set Frame of View 1 of Window 0 to "${tabFrame}"
	
 # shows Terminal on all workspaces, w/o tab only borders, not resizable, movable, minimizable or zoomable, shown in the upper half of the screen not overlapping the Deskbar	
	winpwnr.sh -a Terminal -s ${terminalKeyword} -d -H 8 -w all -G nm,nr,nb,nz -L b
	startWatcher=1
fi


if [ -n "${startWatcher}" ];then
	was_active="true"
	while true;do
		### check to see if our window is inactive but still showing
		active=`hey -o ${QTERMPID} get Active of Window 0`
		if [ "${active}" == "false" ] && [ "${was_active}" == "true" ]
		then
			# when the window is not active it will be moved upward showing a small clickable area of 10x10
			winpwnr.sh -a Terminal -s ${terminalKeyword} -p 0,-${move_by}
			was_active="false"
			[ -z "${continuousWatch}" ] &&	exit
		else
			if [ "${active}" == "true" ] && [ "${was_active}" == "false" ]
				then
					# when the window is active again will be moved downward 
					winpwnr.sh -a Terminal -s ${terminalKeyword} -p 0,${move_by}
					was_active="true"
				fi
			[ -z "${active}" ] && exit
		sleep ${watcherSleepTime}
		fi
	done
fi

This is a script that I’ve been using for a while now to download video clips. It uses youtube-dl for the list of supported_sites and wget for all others.
Make it executable, put it on the Desktop, then just copy the clip URL to the clipboard and double-click the script.

If your network connection is fast enough, give it a few seconds to buffer and watch the clip with MediaPlayer while it downloads. (This is pretty much what Ubertuber does, only this script works more reliably… :stuck_out_tongue: )

    #!/bin/sh

    # The script takes the contents of the clipboard and downloads it
    # with either youtube-dl or - if not a supported site - wget
    #
    # Usage:	0) make script executable and put it on the Desktop
    #			1) copy a clip URL
    #			2) double click script to download to Desktop

    supported_sites="youtube youtu.be vimeo"
    destination=~/Desktop
    clip=$(clipboard -p)

    cd $destination

    # Use youtube-dl if the clip comes from a supported site
    for item in $supported_sites ; do
    	if [[ $clip == *"$item"* ]] ; then
    	# get the clip's filename
    		filename=$(youtube-dl --restrict-filenames --no-part \
    			--no-cache-dir --format best --get-filename "$clip")
    	# download clip in best quality
    		youtube-dl --continue --restrict-filenames --no-part \
    			--no-cache-dir --format best "$clip"
    	# add the clip's URL as attribute
    		addattr META:url "$clip" "$filename"
    	# identify file type
    	# 	mimeset -F "$filename"
    		exit
    	fi
    done

    # Use wget for anything else
    filename=$(basename "$clip")
    wget "$clip"
    addattr META:url "$clip" "$filename"
    # mimeset -F "$filename"

The META:url attribute stores the download URL for reference. TIP: To display it in a Tracker window, you can temporarily copy a Bookmark file into the clip’s folder, and activate the URL attribute from the Tracker window’s menu.

I commented out the mimeset lines, because then I recognize the unwatched clips by their generic icon. :slight_smile:

4 Likes

This is HugeMelanoticRooster, grabs RSS feeds from BBC Weather and shows the weather through notifications

#! /bin/sh

## check if the script is running in background

[ ! -e /tmp/HMR.pid ] && touch /tmp/HMR.pid || ( [ $(alert "The script is currently running in background! 
Do you want to stop it?" "Yes" "No") == "Yes" ] && rm /tmp/HMR.pid )

[ ! -e /tmp/HMR.pid ] && exit

## script variables

local_path="$(dirname $0)"

[ "${local_path}" == "." ] && local_path="$(pwd)"

app_path="${local_path}/$(basename ${0})"

location=

background=

# time between each line of notify

sleep_time=10

uri=https://www.bbc.com/weather/

## if there is not a preferred location the default browser will be found and opened
## the user will look for its location, will copy the link and close the browser
## the script will use the copied link, if valid

if [ -z ${location} ] ; then

	clipboard -r

	alert "No preferred location has been found.
Now I will open the BBC Weather site, you have to look for your location, then copy the resulting link and close your browser." >/dev/null
	
	$(query -a BEOS:APP_SIG==$(catattr -d META:PREF_APP /boot/system/data/mime_db/text/html)) ${uri} &>/dev/null
	
	wait $!
	
	clip=$(clipboard -p)
	
	if [[ "${clip}" =~ ${uri}[0-9]*$ ]] ; then
	
		location=$(echo "$clip" | awk '{print $NF}' FS="/")
	
		clipped=TRUE

	else
	
		alert --stop "The copied link is not valid!" >/dev/null
		
		exit
	
	fi
	
fi

## save location into the script file

[ -z ${clipped+x} ] || sed -i "s/^location=/&${location}/" "${app_path}"

## prompt the user if the script runs once only or keeps running every hour

[ -z ${background} ] && ( [ $(alert "Do you want this script to notify the weather every hour?" "Sure" "No") != "No" ] && sed -i "s/^background=/&1/" "${app_path}" || sed -i "s/^background=/&0/" "${app_path}" )

## main funtion

NotifyWeather ()

{
	
## get the rss from BBC

wget https://weather-broker-cdn.api.bbci.co.uk/en/observation/rss/${location} -O /tmp/bbc-obs

wget https://weather-broker-cdn.api.bbci.co.uk/en/forecast/rss/3day/${location} -O /tmp/bbc-frcst

## get the current weather icon

wget $(awk '/.gif/{gsub(/<[u/][a-z]+>/,"");sub(/^[ ]*/,"");print $0}' /tmp/bbc-frcst | tr -d "\r") -O /tmp/bbc-icon

## get the location name

[ -z ${loc_name+x} ] && loc_name="$(awk '/title/&&/Observations/{gsub(/<[t/][a-z]+>/,"");gsub(/^[ ]+/,"");print $0}' /tmp/bbc-obs | sed 's/.*for *//')"

## notifies the current weather

while read line

do

notify --group "BBC Weather - ${loc_name}" --messageID "Observations" --icon /tmp/bbc-icon \
--title "Current Observation" --onClickApp "text/html" --onClickArgv "${uri}${location}" "${line}"

sleep ${sleep_time}

done <<< "$([ -e /tmp/bbc-obs ] && awk '/description/&&/Temperature/{gsub(/<[d/][a-z]+>/,"");sub(/^[ ]+/,"");for(i=1;i<=NF;i++)print $i}' FS=", " /tmp/bbc-obs)"

## notifies the forecasted weather

while read line

do

## get the day name and its forecast weather

if ([[ "${line}" == *day* ]] || [[ "${line}" == To* ]]) ; then

	title=${line}
	
else

	notify --group "BBC Weather - ${loc_name}" --messageID "Forecast" --icon /tmp/bbc-icon \
--title "Forecast for ${title}" --onClickApp "text/html" --onClickArgv "${uri}${location}" "${line}"

	sleep ${sleep_time}

fi

done <<< "$([ -e /tmp/bbc-frcst ] && awk '/title/&&/Temperature/{gsub(/<[t/][a-z]+>/,"");sub(/^[ ]+/,"");print $1};/description/&&/Temperature/{gsub(/<[d/][a-z]+>/,"");sub(/^[ ]+/,"");for(i=1;i<=NF;i++)print $i}' FS=", " /tmp/bbc-frcst)"

## check if the script is running in background mode

if [ ${background} -eq 0 ] ; then

	rm /tmp/HMR.pid

else

## wait 1 hour if the script has not been stopped

	[ -e /tmp/HMR.pid ] && sleep 3600
	
## if after 1 hour the script has not been stopped run the main function again

	[ -e /tmp/HMR.pid ] && NotifyWeather

fi

}

## run the main function first

NotifyWeather

exit
2 Likes

I got a script going yesterday that’ll rip metadata from song files (w ffmpeg) to fill the Audio:* and Media:* attributes.

I like sorting songs by track and albums by year, so there’s also a small cpp file to add the ‘audio/x-ablum’ filetype, which can be used. Assuming you’re using a hierarchy like ./artist/album/song, the script can treat the song’s parent dir like the Album and add Media:Year and Audio:Artist.

3 Likes

I got a script today to do “directory templating” (it’ll copy attributes over from a “template hierarchy,” following certain rules, to a target directory). I’m just using it to make all folders of a certain kind have the exact same window placement/size, help keep organized.

1 Like

This snippet of code helps to set the system volume smoother than setvolume

#! /bin/bash

Usage()
{
echo "usage: [-lmh] [-id value]
-l : set it loud
-m : set it mute
-i : increase by {value}
-d : decrease by {value}
-h : print this help"
}

read curr_vol min_vol max_vol <<< `setvolume | awk '{gsub(/[:=(),a-zA-Z]/,"");print $1,$2,$3}'`

case ${1} in
	-i)
		if [ -z ${2} ] ; then
			Usage
			exit 1
		fi
		[ ${curr_vol} -le ${max_vol} ] && ( let curr_vol+=${2} ; setvolume ${curr_vol} )
		;;
	-d)
		if [ -z ${2} ] ; then
			Usage
			exit 1
		fi
		[ ${curr_vol} -ge ${min_vol} ] && ( let curr_vol-=${2} ; setvolume ${curr_vol} )
		;;
	-l)
		setvolume ${max_vol}
		;;
	-m)
		setvolume ${min_vol}
		;;
	-h)
		Usage
		;;
	*)
		Usage
		exit 1
		;;
esac
2 Likes

Bloated version:

  • added notify support
  • added ++ and – args. changes volume by 3 (db?)
  • added -r to reset to 0, normal volume
  • loud and mute args now can toggle to the previous value

save it, chmod +x, and use it with ShortCuts

#! /bin/bash

local_path="$(dirname $0)"
[ "${local_path}" == "." ] && local_path="$(pwd)"
app_path="${local_path}/`basename ${0}`"

restore_volume=

NotifyVolume()
{
	notify --group "Volume" --title "Setting Volume to:" \
				--messageID "Volume" --timeout 10 --type progress --progress "`echo "scale=2;($1-($2))/($3-($2))" | bc`" "`echo "100*($1-($2))/(-($2))" | bc`%"
}

RestoreVolume()
{
	if [ -z ${restore_volume} ] ; then
		NotifyVolume `setvolume ${1} | awk '{gsub(/[:=(),a-zA-Z]/,"");print $1,$2,$3}'`
		sed -i "s/^restore_volume=/&${curr_vol}/" "${app_path}"

	else
		if  ( ( [ ${curr_vol} -eq ${min_vol} ] && [ ${1} -eq ${max_vol} ] ) || ( [ ${curr_vol} -eq ${max_vol} ] && [ ${1} -eq ${min_vol} ] ) ) ; then
			setvolume ${1}
		else
			NotifyVolume `setvolume ${restore_volume} | awk '{gsub(/[:=(),a-zA-Z]/,"");print $1,$2,$3}'`
			sed -i "s/^restore_volume=.*/restore_volume=/" "${app_path}"
		fi
	fi
}

CheckVolume()
{
	if ( [ ! -z ${restore_volume} ] && ( [ ${curr_vol} -eq ${min_vol} ] || [ ${curr_vol} -eq ${min_vol} ] ) ) ; then
		curr_vol=${restore_volume}
		sed -i "s/^restore_volume=.*/restore_volume=/" "${app_path}"
	fi
}

Usage()
{
	case ${1} in
		1)
			echo "error : missing or wrong argument"
			;;
		2)
			echo "error : missing value"
			;;
	esac
	echo "usage: `basename ${0}` [-rlmh] [++][--] [-id value]
++ : increase volume by 3
-- : decrease volume by 3
-i : increase volume by {value}
-d : decrease volume by {value}
-r : reset to 0
-l : set it loud / revert
-m : toggle to mute/unmute
-h : print this help"
}

read curr_vol min_vol max_vol <<< `setvolume | awk '{gsub(/[:=(),a-zA-Z]/,"");print $1,$2,$3}'`

case ${1} in
	++)
		CheckVolume
		[ ${curr_vol} -lt ${max_vol} ] && ( let curr_vol+=3 ; NotifyVolume `setvolume ${curr_vol} | awk '{gsub(/[:=(),a-zA-Z]/,"");print $1,$2,$3}'` )			
		;;
	--)
		CheckVolume
		[ ${curr_vol} -gt ${min_vol} ] && ( let curr_vol-=3 ; NotifyVolume `setvolume ${curr_vol} | awk '{gsub(/[:=(),a-zA-Z]/,"");print $1,$2,$3}'` )
		;;
	-i)
		if [ -z ${2} ] ; then
			Usage 2
			exit 1
		fi
		CheckVolume
		[ ${curr_vol} -lt ${max_vol} ] && ( let curr_vol+=${2} ; NotifyVolume `setvolume ${curr_vol} | awk '{gsub(/[:=(),a-zA-Z]/,"");print $1,$2,$3}'` )
		;;
	-d)
		if [ -z ${2} ] ; then
			Usage 2
			exit 1
		fi
		CheckVolume
		[ ${curr_vol} -gt ${min_vol} ] && ( let curr_vol-=${2} ; NotifyVolume `setvolume ${curr_vol} | awk '{gsub(/[:=(),a-zA-Z]/,"");print $1,$2,$3}'` )
		;;
	-r)
		CheckVolume
		NotifyVolume `setvolume 0 | awk '{gsub(/[:=(),a-zA-Z]/,"");print $1,$2,$3}'`
		;;
	-l)
		RestoreVolume ${max_vol}
		;;
	-m)
		RestoreVolume ${min_vol}
		;;
	-h)
		Usage
		;;
	*)
		Usage 1
		exit 1
		;;
esac
5 Likes

The script should check sed and awk are installed.

1 Like