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:

3 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
1 Like

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.

1 Like

After some mishaps (like formatting the wrong pendrive, some kdls overwriting some of my files with their log) I almost totally rewrote and finally finished my feed aggregator based on shell commands, called Borborygmus

Surely it’s totally bug prone, I dunno if you wanna try it but there it is:

https://drive.google.com/file/d/1A9qvWAozxHGoLzvfkflUEcw_ijGI5duP/view?usp=sharing

if you want to try it download the archive , expand it, run install.sh, run Borborygmus.sh in ~ / non-packaged / bin / Borborygmus , this will create a replicant in the Deskbar, right click on it, click “edit subscriptions” to manually add your feeds or import them directly from an OPML file (I tested the ones created by feedly and inoreader, it worked with them) through ‘open Tools’ --> Takeout.sh

Press ‘edit configuration’ to adapt its behaviour to your needs (feeds grouped by keywords, number of words to show in the notification, repeated execution in the background, timeout times, indexes and attributes to use)

each time you click on the replicant icon it will update its content (feeds, or special items to launch the notifications or a query for a ${status}),it could take a while if you have a lot of feeds

click on the name of a feed to start downloading and processing it, new items will be shown via notifications, click again on it to stop, pause or mute it ( when muted, feed items are not notified but saved as New on disk for later reading); feeds can be grouped by keyword if enabled from the configuration file so that you can run / stop all feeds belonging to a keyword,

you can use the parachute actions to stop / unpause / unmute all running feeds, blanket actions allow you to pause / mute all feeds temporarily

Through ‘open tools --> Papain.sh’ you can correctly digest the stored items (saved as html files) ; drag the desired files onto the opened terminal window and press Enter, so you can open the original link of the chosen item, or change its status between Read / New / Saved / Procrastinated

From the menu of the replicant you can start the notification of the items belonging to these states (the new or procrastinated ones will then be marked as read once notified, the saved ones will remain so), or open the queries for each desired state

From the menu you will be able to access the data folder in ~ / non-packaged / settings / zuMis / data which contains the stored item files, the bookmark of the subscribed site and its icon (if you have installed imagemagick it will shrink it to fit better into the notify view) go to its parent and you will find a defaults folder, it contains some folder layouts, modify them to satisfy your needs

probably i forgot say something…if you tried it and hated it, there is a friendly uninstall.sh in its folder