Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - misko_2083

#1
Zenity & Yad / PMRP UI yad
April 27, 2017, 03:49:54 AM
Played a little with this, there are just a few stations, but it looks ok to me.
I have compiled the latest yad and mpg123, so I'm not sure how it works with older versions.

It's a little slow on exit but that's how the remote control works with mpg123. There is a 10 seconds sleep on quit, then if mpg123 doesn't want to quit, we call the "killall".
How to setup? First you need a stations file. I think it's better to keep the stations out of the script. It's easier to maintain them this way.
There are just a few stations in there for now.
Honestly, I lost the willpower after seeing how many stations are there in the original pmrp script  :D
stations file:
## Stations
# Tag: "Name" "Category" "URL"

## 181.FM

181.FM: "Chilled Out" "Techno" "http://relay.181.fm:8700"
181.FM: "Energy 93" "Techno" "http://relay.181.fm:8044"
181.FM: "Energy 98" "Techno" "http://relay.181.fm:8800"
181.FM: "Studio 181" "Techno" "http://relay.181.fm:8072"
181.FM: "Techno Club" "Techno" "http://icyrelay.181.fm/181-technoclub_128k.mp3"
181.FM: "The Vibe of Vegas" "Techno" "http://relay.181.fm:8074"
181.FM: "Jammin 181" "Urban" "http://relay.181.fm:8042"
181.FM: "Old School HipHop" "Urban" "http://relay.181.fm:8068"
181.FM: "The Beat" "Urban" "http://relay.181.fm:8054"
181.FM: "The Box" "Urban" "http://relay.181.fm:8024"
181.FM: "True R&B" "Urban" "http://relay.181.fm:8022"

# Needs at least one empty new line at the end of the list
# to avoid yad list issue

OK, now the script (remember to change the path to stations file in this line => export pmrp_stations="/home/misko/Desktop/pmrpui/stations")
#!/bin/bash
command -v mpg123 >/dev/null 2>&1 || (yad --text="PMRP requires 'mpg123' but it's not installed!\nInstall 'mpg123' to enjoy PMRP."; exit 1)

TEXTDOMAIN=ydesk
TEXTDOMAINDIR=/usr/share/locale

export pmrp='@bash -c "run_stations %1"'
export pmrp_stations="/home/misko/Desktop/pmrpui/stations"

export fpipe=$(mktemp -u --tmpdir pmrp.XXXXXXXX)
export ppipe=$(mktemp -u --tmpdir ppmrp.XXXXXXXX)
export cpipe=$(mktemp -u --tmpdir cpmrp.XXXXXXXX)

mkfifo "$fpipe"
mkfifo "$ppipe"
mkfifo "$cpipe"

trap "rm -f $fpipe $ppipe $cpipe" EXIT

pmkey=$(($RANDOM * $$))

# Categories are separated with "!" (without quotes)
# The last item in category is without trailing "!"
Categories="181.FM!
Blues!
Bollywood!
Classical!
Country!
Electronic!
Hits!
Jazz!
Medley!
Metal!
News_&_Views!
Oldies!
Reggae!
Rock!
SomaFM!
Urban"


function run_stations
{
    echo "2:@disable@"
    echo -e '\f' >> "$fpipe"

    ECHO_ONE='echo "Category: $1" >> "$ppipe"'
    ECHO_TWO='echo "-----------------------" >> "$ppipe"'
    case "$1" in
181.FM)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Blues)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Bollywood)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Classical)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Country)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Electronic)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Hits)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Jazz)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Medley)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Metal)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
"News_&_Views")
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Oldies)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Reggae)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Rock)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
SomaFM)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
Urban)
          echo "Category: $1" >> "$ppipe"
          echo "-----------------------" >> "$ppipe"
  < "$pmrp_stations" sed -n -e 's/^.*'"$1: "'//p' \
          | sed -e $'s/\" \"/\\\n/g;s/\"//g' >> "$fpipe"
    ;;
         *)
          echo "PMRP: Error! No such Category $1" >> "$ppipe"
            ;;
    esac
    echo "2:$pmrp"
}
export -f run_stations



function load_url
{
    echo "Station:$1   Url: $3" >> $ppipe
    echo "load $3" > $cpipe
}
export -f load_url

exec 3<> $fpipe
exec 4<> $ppipe
exec 5<> $cpipe

killall mpg123 2>/dev/null
PLAYER="mpg123 --remote --fifo $cpipe --utf8 --title --preload 1 --buffer 768 --smooth"
$PLAYER 2>&1 /dev/null | tee >(awk '/@E/ || /@P/{if ($0=="@P 0") print "PMRP: playing stopped";
                                                else if ($0=="@P 1") print "PMRP: playing paused";
                                                else if ($0=="@P 2") print "PMRP: playing";
                                                else if ($0 ~ "^@E.") print "PMRP:",$1="",$0;
                                                else print $0; fflush(stdout)}'  >> "$ppipe") \
                            >(awk -F'=' '/StreamTitle/{gsub(/'\''/,"",$2);
                            gsub(/\;/,"",$2); print "Title:", $2; fflush(stdout)}' >> "$ppipe") &>/dev/null &

yad --plug="$pmkey" --tabnum=1 --form --field "Category":CB "$(for category in $Categories; do printf "%s" "$category"; done)" \
    --image=radio --image-ontop --field="Load Stations!gtk-add:fbtn" "$pmrp" &

yad --plug="$pmkey" --tabnum=2 --list --no-markup --dclick-action='bash -c "load_url %s"' \
    --text "Double click to play" --text-align=center --column="Name" --column="Category" --column="Url" \
    --search-column=1 --expand-column=1 --print-column="3" <&3 &

yad --text-info --title="PMRP-Log" --window-icon=radio --posx=710 --posy=100 --width=600 --height=500 --button="gtk-close" <&4 &

echo "PMRP: Ready to Play" >> "$ppipe"

yad --paned --key="$pmkey" --button="Show Log":'bash -c "yad --text-info --title=PMRP-Log --window-icon=radio --posx=710 --posy=100 --width=600 --height=500 < $ppipe" &' \
    --button="Pause/Continue":'bash -c "echo pause >> $cpipe"' \
    --button="Stop":'bash -c "echo stop >> $cpipe"'  --text="Select a Category and click to Load Stations" --width=700 --height=500 \
    --title=$"PMRP" --window-icon="radio" --posx=10 --posy=100

[[ $? == 252 ]] && echo quit >> $cpipe
echo "PMRP: Preparing for radio silence" >> "$ppipe"
# Takes a lot to quit, patience
sleep 10
# Well, sometimes it fails to quit, SIGTERM
killall mpg123 2>/dev/null
echo "PMRP: Zzzzzzz" >> "$ppipe"

exec 3>&-
exec 4>&-
exec 5>&-

#2
Zenity & Yad / youtube-dl wrapper
August 28, 2016, 06:40:55 PM
This is a youtube-dl wrapper; supports videos and lists from YouTube.
https://gitlab.com/misko_2083/yt-get/tags/v0.1.2

- detects if a url is a YT video or a list
- has options to select a custom download format
- can select videos from a list
- multiple GUI modes for single or multiple urls
- can download to mp3





Custom Format selection:

Selecting individual videos from a list:

Multiple download of videos and/or lists:

#3
Scripts / apt-get upgrade and yad
January 12, 2016, 07:54:41 PM
I've been playing with a little script to update packages.
So here is the thing. When a package manager has an exclusive lock and this script tries to start the update, it calls a function to check wheather there is a lock or not.
If there is a lock it opens a Yad progress dialog which waits until the package manager (synaptic, gdebi-gtk, aptitude, apt...) releases the lock.
Now, when I click on Cancel on that same dialog Yad kills the parent process but there is still a child process that is checking the lock.
It eventualy closes when the package manager is closed, but I wonder if there is a way to kill it along with the parent.

The problem is in function checklock. When the synaptic is running and you select the 'Update Packages' from the main dialog, click the Cancel and look for the process with htop.
Any suggestions are welcome.  :)
#!/bin/bash
# Licensed under the GNU GPLv3.
#.%%...%%..%%%%%%...%%%%...%%..%%...%%%%.._.
#.%%%.%%%....%%....%%......%%.%%...%%..%%.2.
#.%%.%.%%....%%.....%%%%...%%%%....%%..%%.0.
#.%%...%%....%%........%%..%%.%%...%%..%%.8.
#.%%...%%..%%%%%%...%%%%...%%..%%...%%%%..3.
# Bash/YAD Debian Package Updater based on Linux Lite update tool
# ------- Change log ------
# Switched to YAD and adapted to Debian
# Added: a main dialog loop, log, option to purge the lists, about dialog
# Added: a check for exclusive lock
# -----------------------------------
# Note:  function checklock -> if Cancel is selected while the package manager (synaptic) is open
#        Yad progress kills the parent but will not kill the child process running the exclusive lock check
#        Subshell will be running until the package manager releases the lock
# -----------------------------------
# Milos Pavlovic
#

APPNAME="Update Tool"
LOGFILE=/var/log/misko-update.log
UPDATELOG=/var/log/last-update-log.log
# dist-upgrade or upgrade, change next line
COMMAND=dist-upgrade
# Yad window icon
ic=/usr/local/bin/images/vsidoorb_80.png

# Make sure only root can run our script
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root!" 1>&2
echo "TIP: Use gksudo or a similar tool." 1>&2
exit 1
fi

function log(){
message="$@"
echo '['$(date +%D\ %H:%M:%S)'] '$message | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})*)?m//g" | fold -sw 76 >>$LOGFILE
}

function checklock () {
# Checks for exclusive lock and wait until package managers are closed
while  fuser /var/lib/dpkg/lock 2>&1 >/dev/null  ; do
echo "# Waiting for other software managers to finish..." $"\n"
if [ "$(pidof synaptic)" ]; then
echo "# Waiting for other software managers to finish..." $"\nsynaptic"
fi
echo 1
sleep 1
echo 30
sleep 1
echo 60
sleep 1
if [ ! -z "$(pgrep gdebi-gtk)" ]; then
echo "# Waiting for other software managers to finish..." $"\ngdebi-gtk"
fi
echo 95
sleep 1
done | yad --progress --title="$APPNAME - close any open package managers" --percentage=20 --auto-close --auto-kill --button="Cancel:1"
if [[ $? -eq 1 ]];then
sleep 1
exit
fi
}


function showlog () {
if [[ ! -f $LOGFILE ]]; then
yad --info --title="$APPNAME Info" --text="No log file."
elif  [[  -z "$(cat $LOGFILE)"  ]]; then
yad --info --title="$APPNAME Info" --text="Log is empty."
else
yad --text-info  --button="Open log in Medit:0" --button="Close:1" --title="$APPNAME log file -> $log" --height=600 --width=800 --filename="$LOGFILE"
if [ "${PIPESTATUS[0]}" -eq "0" ]; then
medit "$LOGFILE" &
fi
fi
return
}

function about () {
yad --info --title="About $APPNAME " --height=20 --width=300 --text="$APPNAME is a small update GUI, fork of Linux Lite Upgrade tool and very easy to use.\n\nLicence GPL v3.\n\n Milos Pavlovic 2016"
return
}

function update() {

# Temporary file for error tracking
TMPLIST=$(mktemp /tmp/repos.XXXXXX)

APTUPDATE=$(grep '^deb' -c /etc/apt/sources.list) # Total number of repositories registered, this is approximated

apt-get update 2>&1 | tee $TMPLIST | awk -v total=$APTUPDATE '/^Ign|^Get/{count++;$1=""} FNR { if (total != 0){percentage=int (100*count/total);print (percentage < 90?percentage:90),"\n#",substr($0, 0, 128) }; fflush(stdout)}' \
| yad --progress --text="Updating package lists..." --window-icon="$ic" --title="Updating Software Sources - please wait..." --percentage=0 --auto-close --width=600

if [ "${PIPESTATUS[0]}" -ne "0" ]; then
err_msg=$(awk '/^(W:|E:)/{$1=""; print $0}' $TMPLIST | tail -n 1 ) #Get errors/warnings
log "ERROR: $err_msg"
unset APTUPDATE
rm -f $TMPLIST
unset TMPLIST
yad --error \
--title="Error" --text="$APPNAME couldn't fetch the package cache information lists.\nCheck the log for details"

return
fi

log "INFO: Software sources were updated."

unset APTUPDATE
rm -f $TMPLIST
unset TMPLIST

#  Temporary list of available updates
UPDATES=$(mktemp /tmp/updateslist.XXXXXX)

# Creates a list in /tmp/updateslist
apt-get --just-print $COMMAND 2>&1 | perl -ne 'if (/Inst\s([\w,\-,\d,\.,~,:,\+]+)\s\[([\w,\-,\d,\.,~,:,\+]+)\]\s\(([\w,\-,\d,\.,~,:,\+]+)\)? /i) {print "Name: $1 INSTALLED: $2 AVAILABLE: $3\n"}' | awk '{print NR,":\t"$0}' \
| tee $UPDATES  | yad --progress --window-icon="$ic" --pulsate --title="Calculating Updates" --text="Please wait..." --auto-close

# Check if any updates are available, if there are none, script pops up dialog box saying 'No Updates Available', removes /tmp/updateslist.XXXXXX
if [  -z "$(cat $UPDATES)"  ]; then
log "INFO: No updates are available."
rm -f $UPDATES
unset UPDATES
yad --info --window-icon=$ic --title="$APPNAME" \
--text="No Updates Available"

return
fi
# Log available updates
    lst_upgrades=$(awk 'BEGIN { FS = "[ ]" } { print $3 }' $UPDATES)
    log "INFO: Updates available: $lst_upgrades"
    unset lst_upgrades

# Insert text into  /tmp/updateslist.XXXXXX
sed -i -e '1 i\List of available Updates' -e '1 i\Click Update to continue or Cancel to stop the update process\n'  $UPDATES

# Erase existing available info
sudo dpkg --clear-avail

# Call the yad dialog to show update list
yad --text-info --window-icon="$ic" --ok-label="Update" --cancel-label="Cancel" --title="Available Updates" --width=780 --height=300 --filename="$UPDATES"

# Continue script if no halt
if [ "$?" -eq "0" ];then


# Write log
log "INFO: Update started."

# Remove tmp file and unset variable
rm -f $UPDATES
unset UPDATES

# Begin upgrade
DEBIAN_FRONTEND=noninteractive apt-get  -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" $COMMAND --show-progress -y  2>&1 | tee $UPDATELOG | awk ' BEGIN { FS=" "; total=1;end_download=0} /upgraded/ {total= $1 + $3;FS="[ :]" } /^Get:[[:digit:]]+/ {printf "#Downloading %s %s %s\n",$5,$(NF-1),$NF;print int(($2 - 1) * 100 / total); fflush(stdout)} /^\(Reading / {if (end_download==0){print 100;fflush(stdout);end_download=1}} /^(Preparing|Unpacking|Selecting|Processing|Setting|Download)/ {print "#", $0; fflush(stdout)}  /^Progress/ {print  match($0, /([0-9]+)/, arr); if(arr[1] != "") print arr[1] ; fflush(stdout)}' \
| ( yad --window-icon=$ic --progress --width=600 --text="Downloading package(s)...\nThis may take a while." --title="Downloading - please wait..." --percentage=0 --auto-close ; yad --progress --window-icon=$ic --width=600 --text="Installing and configuring packages...\nThis may take a while." --title="Installing - please wait..." --auto-close )

if [ "${PIPESTATUS[0]}" -ne "0" ]; then
err_msg=$(awk '/^(W:|E:)/{$1=""; print $0}' $UPDATELOG | tail -n 1)
log "ERROR:$err_msg"
yad --error \
--title="Error" --window-icon="$ic" --text="Updates have failed.\nCheck the log for details."
return
fi

# Halt updates script if user selects Cancel
else
log "INFO: User has canceled software upgrades."
rm -f $UPDATES
unset UPDATES
return
fi

log "INFO: Updates successfully installed."

PROCEED=$(yad --question --title="$APPNAME" --text="Updates have finished installing.\n\nWould you like to view the $APPNAME log?"; echo $?)

if [ ${PROCEED} -eq 1 ]; then
yad --info --title="$APPNAME" --text="Updates Complete."
return;
else
yad --text-info --ok-label="Quit" --cancel-label="Cancel" --title="Updates Log" --width=700 --height=300 --filename="$UPDATELOG"
fi

return
}


# Start the main loop
while (true); do
selection=$(yad --list --radiolist --title="$APPNAME" --window-icon="$ic" --text="Pick a task" --height=310 --width=350 --hide-column=2 --button="Exit:1" --button="Select:0" --column="Pick" --column="Function" --column="Task" \
"TRUE" "update" "Update Packages" "FALSE" "showlog" "Show log" "FALSE" "purgecache" "Purge the old cache" "FALSE" "about" "About this application" "FALSE" "exit" "Exit" --print-column=2) || exit
selection=$(echo $selection | cut -d '|' -f 1)

case "$selection" in
update) checklock; update
;;
showlog) showlog
;;
purgecache) checklock; sudo rm -vfd /var/lib/apt/lists/*  || yad --error --text="Error while purging the cache\nTry doing it manualy\nsudo rm -vfd /var/lib/apt/lists/* "
;;
about) about
;;
exit) exit 0
;;
esac
done
#4
Scripts / WinTricks
December 17, 2015, 01:50:26 AM
Found this script on LXLE, and it's really interesting.
Wasn't hard to make it run on VSIDO. I've just changed three lines to make it compatible with fluxbox :)
Tiles up windows and allows you to choose one. When you choose a window it resizes the windows back to original dimensions and brings selected window to focus.
The script start's when the mouse pointer stays longer than a second in the  top left corner of the screen. Uses xautolock daemon to detect mouse pointer position.
xautolock -locker "/usr/local/bin/winfuncs 'select'" -corners +000 -cornerdelay 1
So the autostart command would be.
xautolock -locker "/usr/local/bin/winfuncs 'select'" -corners +000 -cornerdelay 1 &
But first => apt-get install xautolock
Here is the script => /usr/local/bin/winfuncs
#!/bin/bash
# todo:
# cancel for tile functions
# determine what windows are maximized and re-max after the "window select" function
# determine what windows are non-resizable by the user so that the script doesn't resize them
# cascade also shaded windows
# which workspace we're on

function get_workspace {
        if [[ "$DTOP" == "" ]] ; then
            DTOP=`xdotool get_desktop`
        fi
}

function is_desktop {
xwininfo -id "$*" | grep '"Desktop"'
return "$?"
}

function get_visible_window_ids {
if (( ${#WDOWS[@]} == 0 )) ; then
WDOWS=(`xdotool search --desktop $DTOP --onlyvisible "" 2>/dev/null`)
fi
}

function get_desktop_dim {
#desktop dimensions
if (( ${#DIM[@]} == 0 )) ; then
DIM=(`wmctrl -d | egrep "^0" | sed 's/.*DG: \([0-9]*x[0-9]*\).*/\1/g' | sed 's/x/ /g'`)
fi
}

function win_showdesktop {
get_workspace
get_visible_window_ids

command="search --desktop $DTOP \"\""

if (( ${#WDOWS[@]} > 0 )) ; then
command="$command windowminimize %@"
else
command="$command windowraise %@"
fi

echo "$command" | xdotool -
}

function win_tile_two {
get_desktop_dim
wid1=`xdotool selectwindow 2>/dev/null`

is_desktop "$wid1" && return

wid2=`xdotool selectwindow 2>/dev/null`

is_desktop "$wid2" && return

half_w=`expr ${DIM[0]} / 2`

commands="windowsize $wid1 $half_w ${DIM[1]}"
commands="$commands windowsize $wid2 $half_w ${DIM[1]}"
commands="$commands windowmove $wid1 0 0"
commands="$commands windowmove $wid2 $half_w 0"
commands="$commands windowactivate $wid1"
commands="$commands windowactivate $wid2"

wmctrl -i -r $wid1 -b remove,maximized_vert,maximized_horz
wmctrl -i -r $wid2 -b remove,maximized_vert,maximized_horz

echo "$commands" | xdotool -
}

function win_tile {
get_workspace
get_visible_window_ids

(( ${#WDOWS[@]} < 1 )) && return;

get_desktop_dim

# determine how many rows and columns we need
cols=`echo "sqrt(${#WDOWS[@]})" | bc`
rows=$cols
wins=`expr $rows \* $cols`

if (( "$wins" < "${#WDOWS[@]}" )) ; then
cols=`expr $cols + 1`
wins=`expr $rows \* $cols`
if (( "$wins" < "${#WDOWS[@]}" )) ; then
    rows=`expr $rows + 1`
    wins=`expr $rows \* $cols`
fi
fi

(( $cols < 1 )) && cols=1;
(( $rows < 1 )) && rows=1;

win_w=`expr ${DIM[0]} / $cols`
win_h=`expr ${DIM[1]} / $rows`

# do tiling
x=0; y=0; commands=""
for window in ${WDOWS[@]} ; do
wmctrl -i -r $window -b remove,maximized_vert,maximized_horz

commands="$commands windowsize $window $win_w $win_h"
commands="$commands windowmove $window `expr $x \* $win_w` `expr $y \* $win_h`"

x=`expr $x + 1`
if (( $x > `expr $cols - 1` )) ; then
    x=0
    y=`expr $y + 1`
fi
done

echo "$commands" | xdotool -
}

function win_cascade {
get_workspace
get_visible_window_ids

(( ${#WDOWS[@]} < 1 )) && return;

x=0; y=0; commands=""
for window in ${WDOWS[@]} ; do
wmctrl -i -r $window -b remove,maximized_vert,maximized_horz

commands="$commands windowsize $window 640 480"
commands="$commands windowmove $window $x $y"

x=`expr $x + 22`
  y=`expr $y + 22`
done

echo "$commands" | xdotool -
}

function win_select {
get_workspace
get_visible_window_ids

(( ${#WDOWS[@]} < 1 )) && return;

# store window positions and widths
i=0
for window in ${WDOWS[@]} ; do
GEO=`xdotool getwindowgeometry $window | grep Geometry | sed 's/.* \([0-9].*\)/\1/g'`;
height[$i]=`echo $GEO | sed 's/\(.*\)x.*/\1/g'`
width[$i]=`echo $GEO | sed 's/.*x\(.*\)/\1/g'`

# ( xwininfo gives position not ignoring titlebars and borders, unlike xdotool )
POS=(`xwininfo -stats -id $window | grep 'geometry ' | sed 's/.*[-+]\([0-9]*[-+][0-9*]\)/\1/g' | sed 's/[+-]/ /g'`)
posx[$i]=${POS[0]}
posy[$i]=${POS[1]}

i=`expr $i + 1`
done

# tile windows
win_tile

# select a window
wid=`xdotool selectwindow 2>/dev/null`

is_desktop "$wid" && return

# restore window positions and widths
i=0; commands=""
for (( i=0; $i<${#WDOWS[@]}; i++ )) ; do
commands="$commands windowsize ${WDOWS[i]} ${height[$i]} ${width[$i]}"
commands="$commands windowmove ${WDOWS[i]} ${posx[$i]} ${posy[$i]}"
done

commands="$commands windowactivate $wid"

echo "$commands" | xdotool -
}

for command in ${@} ; do
if [[ "$command" == "tile" ]] ; then
win_tile
elif [[ "$command" == "select" ]] ; then
win_select
elif [[ "$command" == "tiletwo" ]] ; then
win_tile_two
elif [[ "$command" == "cascade" ]] ; then
win_cascade
elif [[ "$command" == "showdesktop" ]] ; then
win_showdesktop
fi
done

The script can do some more stuff with windows
/usr/local/bin/winfuncs 'showdesktop'
/usr/local/bin/winfuncs 'cascade'
/usr/local/bin/winfuncs 'tile'
/usr/local/bin/winfuncs 'tiletwo'
"Tile Two" is interesting, it tiles two windows next to each other.
#5
Scripts / gtk3 Volume Control for tint2
December 17, 2015, 01:24:04 AM
My attempt to make a volume control context menu that launches from tint2.
Uses amixer
It wasn't showing properly untill I've installed libgtk-3-0
Here is the launcher =>
/usr/local/bin/tint2launchers/07-sound.desktop
[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=Sound
Exec=python3 /usr/local/bin/menu.py
Icon=audio-headphones
NoDisplay=false


py script
/usr/local/bin/menu.py
#!/usr/bin/env python3
#  Milos Pavlovic 2015 <mpsrbija@gmail.com>
#
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.

#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.

#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.


import os
import sys
import string
import subprocess
import shlex
from gi import require_version
require_version("Gtk", "3.0")
from gi.repository import Gtk
from gi.repository.GdkPixbuf import Pixbuf

def execute(command):
    """function to exec switch"""
    p = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    return p.stdout

class Menu:

    def destroy(self, widget, data=None):
        Gtk.main_quit()

    def action(self, widget, event, execc, data=None):
        command = execc
        subprocess.Popen(shlex.split(command), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        Gtk.main_quit()

    def __init__(self):
        self.menu = Gtk.Menu()
        """ This is how we close the script
            connecting to the hide signal
        """
        self.menu.connect("hide", self.destroy)
        it=Gtk.IconTheme.get_default()
        height = 100 # Height workaround

        button= Gtk.Switch()
        button.connect("notify::active", self.on_switch_activated)
        cmd = 'amixer get Master | grep -q  off ; echo $?'
        result1 = os.popen(cmd)
        result1 = result1.readline()
        if int(result1) == 0:
           button.set_active(False)
        else:
           button.set_active(True)
        box = Gtk.Box(homogeneous =True)
        img = Gtk.Image(xalign=0)
        pixbuf=it.load_icon("emblem-sound",24,0)
        img.set_from_pixbuf(pixbuf)
        box.add(img)
        box.add(button)
        menuitem = Gtk.MenuItem()
        menuitem.add(box)
        menuitem.connect("button-press-event", self.mute_clicked)
        menuitem.show()
        self.menu.append(menuitem)

# adjustment (initial value, min value, max value,
        # step increment - press cursor keys to see!,
        # page increment - click around the handle to see!,
        # page size - not used here)
        ad1 = Gtk.Adjustment(0, 0, 100, 5, 10, 0)
        cmd = "/usr/bin/amixer sget Master | grep '\[' "
        result = os.popen(cmd)
        result = result.readline()
        find_start = result.find('[') + 1
        find_end = result.find('%]', find_start)
        audio_level = int(result[find_start:find_end])
        ad1. set_value(audio_level)
        # an horizontal scale
        self.h_scale = Gtk.Scale(
            orientation=Gtk.Orientation.HORIZONTAL, adjustment=ad1)
        # of integers (no digits)
        self.h_scale.set_digits(0)
        # that can expand horizontally if there is space in the grid
        self.h_scale.set_hexpand(True)
        # that is aligned at the top of the space allowed in the grid
        self.h_scale.set_valign(Gtk.Align.START)

        # we connect the signal "value-changed" emitted by the scale with the callback
        # function scale_moved
        self.h_scale.connect("value-changed", self.scale_moved)
        box = Gtk.Box()
        box.add(self.h_scale)
        menuitem = Gtk.MenuItem()
        menuitem.add(box)
        menuitem.show()
        self.menu.append(menuitem)

        self.menu.set_size_request(180, height) # Workaround for height
        self.menu.popup(None, None, None, None, 0, Gtk.get_current_event_time())
        self.menu.show_all()

    # Let's set the voulume here
    def scale_moved(self, event):
        val = "{0}".format(int(self.h_scale.get_value()))
        proc = subprocess.Popen('/usr/bin/amixer sset Master ' + str(val) + '%  2>&1 >/dev/null', shell=True, stdout=subprocess.PIPE)
        proc.wait()

    def on_switch_activated(self, switch, gparam):
        if switch.get_active():
            execute('amixer set Master unmute 2>&1 >/dev/null')
            state = "on"
        else:
            execute('amixer set Master mute 2>&1 >/dev/null')
            state = "off"

    # Here we toogle the mute on and off when menuitem is clicked   
    def mute_clicked(self, event, data=None):
        val = "toggle"
        proc = subprocess.Popen('/usr/bin/amixer set Master ' + str(val) + '  2>&1 >/dev/null', shell=True, stdout=subprocess.PIPE)
        proc.wait()

    def main(self):
        Gtk.main()

if __name__ == "__main__":

     app = Menu()
     app.main()

The script closes when clicked outside of the menu.
There is a mute switch but will work as a button also.
reference from here >>> http://vsido.org/index.php?topic=1089.msg12301#msg12301
#6
This will display all of your mounted usb drives, then you select one.
The script will analyze the contents of the drive and display info about file types and size that file type takes on a drive.
I took some code from "makethumb" script and modified it for my needs.
As you can see it tell me how much space are images taking on this usb drive.

#!/bin/bash
# A GUI tool to analyze the usb drive content
# Misko
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# 3 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.

# Make temporary file
list=$(mktemp /tmp/XXXXXX)

# get a list of devices
devs=`ls -al /dev/disk/by-path/*usb*part* 2>/dev/null | awk '{print($11)}'`
if [[ ${?} != 0 || -z ${devs} ]]
then
    zenity --warning --text "No USB Mounted!"
    exit
fi

# Initialize list and make sure it is empty
>$list

# Now get the info about our devices and put it in a list
for dev in $devs; do dev="${dev##*\/}";
    echo "FALSE" >> $list;
    echo -n "$dev" >> $list;
    echo " " >> $list;
    echo `cat /sys/block/${dev:0:3}/device/vendor 2>/dev/null` >> $list;
    echo `cat /sys/block/${dev:0:3}/device/model 2>/dev/null` >> $list;
    echo `lsblk 2>/dev/null | grep \`echo -E ${dev}\` |awk '{print($4)}' `B >> $list;
    echo `lsblk 2>/dev/null | grep \`echo -E ${dev}\` |cut -c 37- ` >> $list;
    echo -n `lsblk -o NAME 2>/dev/null | grep \`echo -E ${dev}\`| awk '{print($2)}'  ` >> $list;
    df -T `echo -E /dev/${dev}` 2>/dev/null | tail -1 | awk '{print $2}' >> $list;
    echo `ls -l /dev/disk/by-uuid/ 2>/dev/null | grep \`echo -E ${dev}\`| awk '{print($9)}' ` >> $list;
        done


# clear our array
devfs=()

# read in the array using a line tmp variable. This let's zenity see it line by line
while read -r line
do
    devfs+=("$line")
done < $list

rm $list
unset list

#Display the main dialog
disktmp=$(zenity --list --text="Select your USB drive from the list and click OK to begin.\nThis will calculate what file types you have on the drive and how much space do they consume.\nThe speed of this process depends on the drive size and on the number of files." --radiolist  --width=650 --height=350 --column="Pick" --column="Dev" --column="Vendor" --column="Model" --column="Size" --column="Mount" --column="FS" --column="UUID" "${devfs[@]}" --separator=":")

#Test for cancellation
if [[ ${?} != 0  ]]
then
    exit 0
fi

#Check if anything was selected
echo ${disktmp} | grep ^[0-9a-zA-Z] &>/dev/null
if [[ ${?} != 0  ]]
then
    zenity --info --text="Nothing was selected..." --timeout=10
    exit 0
fi
# Extract device
disk=${disktmp:0:4}

# Start calculating file sizes and convert bytes to human readable
{
echo "#Please wait, this may take a while"
find "$(echo `lsblk 2>/dev/null | grep \`echo -E ${disk}\` |cut -c 37- `)" -type f -exec file -b '{}' \; -printf '%s\n' | awk -F , 'NR%2 {i=$1} NR%2==0 {a[i]+=$1} END {for (i in a) printf("%12u %s\n",a[i],i)}' | sed -e 's/^[ \t]*//' > ~/usbinform
echo "#Calculating File size"
awk '{print $1}' ~/usbinform | awk '{ sum=$1 ; hum[1024**3]="GiB";hum[1024**2]="MiB";hum[1024]="KiB"; for (x=1024**3; x>=1024; x/=1024){ if (sum>=x) { printf "%.2f %s\n",sum/x,hum[x];break } if (sum<1024) {printf sum" bytes\n";break } }}' > ~/usbinform1
awk '{print $1}' ~/usbinform | awk '{ sum=$1 ; hum[1000**3]="GB";hum[1000**2]="MB";hum[1000]="KB"; for (x=1000**3; x>=1000; x/=1000){ if (sum>=x) { printf "%.2f %s\n",sum/x,hum[x];break } if (sum<1000) {printf sum" bytes\n";break } }}' > ~/usbinform2
sed -i 's/\w*.//' ~/usbinform
} | zenity --progress --pulsate --auto-close || exit

# Display results
paste -d'\n' ~/usbinform2 ~/usbinform1 ~/usbinform | zenity --list --title="${disk}" --column="Size" --column="Size KiB" --column="Description" --width=800 --height=650 --ok-label="Save" --cancel-label="OK" --text="Drive ${disk} Storage Summary\n1KB=1000 bytes, 1KiB=1024 bytes"

#Test for cancellation
if [[ ${?} != 0 ]]
then
    rm ~/usbinform
    rm ~/usbinform1
    rm ~/usbinform2
       exit 0
fi

#Ask where to save our file
zNewData=$(paste -d'\t' ~/usbinform2 ~/usbinform1 ~/usbinform)
zSavePath=$(echo -n "$(zenity --file-selection --save --confirm-overwrite --filename="USBdrive_summary.txt" --title="Save USB drive info")")

#Test for cancellation
if [[ ${?} != 0 ]]
then
    rm ~/usbinform
    rm ~/usbinform1
    rm ~/usbinform2
       exit 0
fi

#save
echo -n "$zNewData" > "$zSavePath"

# Remove temp files
rm ~/usbinform
rm ~/usbinform1
rm ~/usbinform2
exit

Edit: lol a small error fixed not 38 it's 37   ::)
#7
Zenity & Yad / checksums
May 18, 2015, 02:50:51 PM
This is a script I made for the thunar custom action.
Depends on zenity and pv.
Calculates md5, sha1 and sha2 sums.
I use pv to show progress with zenity --progress dialogue.
Make sure to install pv
apt-get install zenity pv

-save the script as checksum
-make executable
-copy the file to /usr/local/bin

#!/bin/bash
# Purpose:  Thunar Custom Action. Calculates hashes.
# Usage:     /usr/local/bin/checksum %f
# Author:    Misko_2083
# Date:       May, 2015
# Version:    1.2
# Licence GPLv2
# Dependancy: zenity, pv

file="$@"

# Check that the user didn't select directory
if [ -d "$file" ]; then
zenity --error --text="'$file' is a directory. Checksum cannot handle directories."
exit
fi

MD5=(`echo "" | awk '{print "TRUE","MD5", $0}'`)
SHA1=(`echo "" | awk '{print "FALSE","SHA-1", $0}'`)
SHA224=(`echo "" | awk '{print "FALSE","SHA-224", $0}'`)
SHA256=(`echo "" | awk '{print "FALSE","SHA-256", $0}'`)
SHA384=(`echo "" | awk '{print "FALSE","SHA-384", $0}'`)
SHA512=(`echo "" | awk '{print "FALSE","SHA-512", $0}'`)

selection=$(zenity --list --radiolist --height=300 --title="Checksum" --text="File:  <b>${file##*/}</b>\nPick the hash function." --column="Pick" --column="Hash" "${MD5[@]}" "${SHA1[@]}" "${SHA224[@]}" "${SHA256[@]}" "${SHA384[@]}" "${SHA512[@]}")

# If Cancel is clicked then exit
if [ $? != "0" ]; then
    exit 0
fi

# Creates a temp file to store the hash sum
sum_temp=$(mktemp /tmp/sum.XXXXXXXX)


# If there is a pipe file removes it
if [[ -p /tmp/checksum_fifo ]]; then
rm /tmp/checksum_fifo || `zenity --error --text="<tt>Could not remove <i>/tmp/checksum_fifo</i>\nCheck the file permissions.</tt>" && exit 1`
fi

# Create a named pipe for storing percentage from pv
mkfifo --mode=0666 /tmp/checksum_fifo

echo $selection | grep "MD5" > /dev/null
if [ $? = 0 ];then
   # Creates a subshell and sends progress to the named pipe
   ( pv -n "$file" | md5sum 2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) ) 2>/tmp/checksum_fifo &
PVPID=$!

    # Creates a subshell and reads progress from the named pipe
   ( zenity --progress --title="MD5sum" --text="Calculating MD5 for:\n${file##*/}" --percentage=0 --auto-close </tmp/checksum_fifo;

# If Cancel is clicked
if [ $? = 1 ];then
# Kill the sum process
kill $PVPID;
# Removes the tmp file and the pipe
rm $sum_temp;
rm /tmp/checksum_fifo
# Kill off this app
killall checksum;

fi;
# Removes the pipe file
rm /tmp/checksum_fifo ) &
ZENPID=$!

   #Wait until progressbar process finishes
   wait $ZENPID
   
    #Displays results
    sum=`cat $sum_temp`
    zenity --info --title="MD5sum" --text="MD5sum : $sum\nFile :          ${file##*/}" --no-wrap
   
    #Cleanup
    rm $sum_temp
    exit 0
fi

echo $selection | grep "SHA-1" > /dev/null
if [ $? = 0 ];then
    # Creates a subshell and sends progress to the named pipe
   ( pv -n "$file" | sha1sum 2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) ) 2>/tmp/checksum_fifo &
PVPID=$!

    # Creates a subshell and reads progress from the named pipe
   ( zenity --progress --title="MD5sum" --text="Calculating SHA-1 for:\n${file##*/}" --percentage=0 --auto-close </tmp/checksum_fifo;

# If Cancel is clicked
if [ $? = 1 ];then
# Kill the sum process
kill $PVPID;
# Removes the tmp file and the pipe
rm $sum_temp;
rm /tmp/checksum_fifo
# Kill off this app
killall checksum;

fi;
# Removes the pipe file
rm /tmp/checksum_fifo ) &
ZENPID=$!

   #Wait until progressbar process finishes
   wait $ZENPID
   
    #Displays results
    sum=`cat $sum_temp`
    zenity --info --title="SHA-1" --text="SHA-1: $sum\nFile :    ${file##*/}" --no-wrap

    #Cleanup
    rm $sum_temp
    exit 0
fi

echo $selection | grep "SHA-224" > /dev/null
if [ $? = 0 ];then
   # Creates a subshell and sends progress to the named pipe
   ( pv -n "$file" | sha224sum  2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) ) 2>/tmp/checksum_fifo &
PVPID=$!

    # Creates a subshell and reads progress from the named pipe
   ( zenity --progress --title="MD5sum" --text="Calculating SHA-224 for:\n${file##*/}" --percentage=0 --auto-close </tmp/checksum_fifo;

# If Cancel is clicked
if [ $? = 1 ];then
# Kill the sum process
kill $PVPID;
# Removes the tmp file and the pipe
rm $sum_temp;
rm /tmp/checksum_fifo
# Kill off this app
killall checksum;

fi;
# Removes the pipe file
rm /tmp/checksum_fifo ) &
ZENPID=$!

   #Wait until progressbar process finishes
   wait $ZENPID
   
    #Displays results
    sum=`cat $sum_temp`
    zenity --info --title="SHA-224" --text="SHA-224 : $sum\nFile :         ${file##*/}" --no-wrap

    #Cleanup
    rm $sum_temp
    exit 0
fi

echo $selection | grep "SHA-256" > /dev/null
if [ $? = 0 ];then
    # Creates a subshell and sends progress to the named pipe
   ( pv -n "$file" | sha256sum 2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) ) 2>/tmp/checksum_fifo &
PVPID=$!

    # Creates a subshell and reads progress from the named pipe
   ( zenity --progress --title="MD5sum" --text="Calculating SHA-256 for:\n${file##*/}" --percentage=0 --auto-close </tmp/checksum_fifo;

# If Cancel is clicked
if [ $? = 1 ];then
# Kill the sum process
kill $PVPID;
# Removes the tmp file and the pipe
rm $sum_temp;
rm /tmp/checksum_fifo
# Kill off this app
killall checksum;

fi;
# Removes the pipe file
rm /tmp/checksum_fifo ) &
ZENPID=$!

   #Wait until progressbar process finishes
   wait $ZENPID
   
    #Displays results
    sum=`cat $sum_temp`
    zenity --info --title="SHA-256" --text="SHA-256 : $sum\nFile :          ${file##*/}" --no-wrap

    #Cleanup
    rm $sum_temp
    exit 0
fi

echo $selection | grep "SHA-384" > /dev/null
if [ $? = 0 ];then
    # Creates a subshell and sends progress to the named pipe
   ( pv -n "$file" | sha384sum 2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) ) 2>/tmp/checksum_fifo &
PVPID=$!

    # Creates a subshell and reads progress from the named pipe
   ( zenity --progress --title="MD5sum" --text="Calculating SHA-384 for:\n${file##*/}" --percentage=0 --auto-close </tmp/checksum_fifo;

# If Cancel is clicked
if [ $? = 1 ];then
# Kill the sum process
kill $PVPID;
# Removes the tmp file and the pipe
rm $sum_temp;
rm /tmp/checksum_fifo
# Kill off this app
killall checksum;

fi;
# Removes the pipe file
rm /tmp/checksum_fifo ) &
ZENPID=$!

   #Wait until progressbar process finishes
   wait $ZENPID
   
    #Displays results
    sum=`cat $sum_temp`
    zenity --info --title="SHA-384" --text="SHA-384 : $sum\nFile :         ${file##*/}" --no-wrap

    #Cleanup
    rm $sum_temp
    exit 0
fi

echo $selection | grep "SHA-512" > /dev/null
if [ $? = 0 ];then
    # Creates a subshell and sends progress to the named pipe
   ( pv -n "$file" | sha512sum 2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) ) 2>/tmp/checksum_fifo &
PVPID=$!

    # Creates a subshell and reads progress from the named pipe
   ( zenity --progress --title="MD5sum" --text="Calculating SHA-512 for:\n${file##*/}" --percentage=0 --auto-close </tmp/checksum_fifo;

# If Cancel is clicked
if [ $? = 1 ];then
# Kill the sum process
kill $PVPID;
# Removes the tmp file and the pipe
rm $sum_temp;
rm /tmp/checksum_fifo
# Kill off this app
killall checksum;

fi;
# Removes the pipe file
rm /tmp/checksum_fifo ) &
ZENPID=$!

   #Wait until progressbar process finishes
   wait $ZENPID
   
    #Displays results
    sum=`cat $sum_temp`
    zenity --info --title="SHA-512" --text="SHA-512 : $sum\nFile :           ${file##*/}" --no-wrap

    #Cleanup
    rm $sum_temp
    exit 0
fi


This is how to setup a Thunar Custom Action:
Name: Checksum
Description: Computes checksum.
Command: /usr/local/bin/checksum %f
Pattern: *
Appearance: Check all the boxes except Directories

After setting this up, you can  right click on an *.iso file and test this.

If you don't want to install thunar file manager, you can use a version with file-selection dialogue:

#!/bin/bash
# Purpose:  Calculates hashes.
# Usage:     /usr/local/bin/checksum
# Author:    Misko_2083
# Date:       May, 2015
# Version:    1.2
# Licence GPLv2
# Dependancy: zenity, pv

#Select the file
file="$(zenity --file-selection --title=Select file)"

# Check that the user didn't select directory
if [ -d "$file" ]; then
zenity --error --text="'$file' is a directory. Checksum cannot handle directories."
exit
fi

MD5=(`echo "" | awk '{print "TRUE","MD5", $0}'`)
SHA1=(`echo "" | awk '{print "FALSE","SHA-1", $0}'`)
SHA224=(`echo "" | awk '{print "FALSE","SHA-224", $0}'`)
SHA256=(`echo "" | awk '{print "FALSE","SHA-256", $0}'`)
SHA384=(`echo "" | awk '{print "FALSE","SHA-384", $0}'`)
SHA512=(`echo "" | awk '{print "FALSE","SHA-512", $0}'`)

selection=$(zenity --list --radiolist --height=300 --title="Checksum" --text="File:  <b>${file##*/}</b>\nPick the hash function." --column="Pick" --column="Hash" "${MD5[@]}" "${SHA1[@]}" "${SHA224[@]}" "${SHA256[@]}" "${SHA384[@]}" "${SHA512[@]}")

# If Cancel is clicked then exit
if [ $? != "0" ]; then
    exit 0
fi

# Creates a temp file to store the hash sum
sum_temp=$(mktemp /tmp/sum.XXXXXXXX)


# If there is a pipe file removes it
if [[ -p /tmp/checksum_fifo ]]; then
rm /tmp/checksum_fifo || `zenity --error --text="<tt>Could not remove <i>/tmp/checksum_fifo</i>\nCheck the file permissions.</tt>" && exit 1`
fi

# Create a named pipe for storing percentage from pv
mkfifo --mode=0666 /tmp/checksum_fifo

echo $selection | grep "MD5" > /dev/null
if [ $? = 0 ];then
   # Creates a subshell and sends progress to the named pipe
   ( pv -n "$file" | md5sum 2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) ) 2>/tmp/checksum_fifo &
PVPID=$!

    # Creates a subshell and reads progress from the named pipe
   ( zenity --progress --title="MD5sum" --text="Calculating MD5 for:\n${file##*/}" --percentage=0 --auto-close </tmp/checksum_fifo;

# If Cancel is clicked
if [ $? = 1 ];then
# Kill the sum process
kill $PVPID;
# Removes the tmp file and the pipe
rm $sum_temp;
rm /tmp/checksum_fifo
# Kill off this app
killall checksum;

fi;
# Removes the pipe file
rm /tmp/checksum_fifo ) &
ZENPID=$!

   #Wait until progressbar process finishes
   wait $ZENPID
   
    #Displays results
    sum=`cat $sum_temp`
    zenity --info --title="MD5sum" --text="MD5sum : $sum\nFile :          ${file##*/}" --no-wrap
   
    #Cleanup
    rm $sum_temp
    exit 0
fi

echo $selection | grep "SHA-1" > /dev/null
if [ $? = 0 ];then
    # Creates a subshell and sends progress to the named pipe
   ( pv -n "$file" | sha1sum 2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) ) 2>/tmp/checksum_fifo &
PVPID=$!

    # Creates a subshell and reads progress from the named pipe
   ( zenity --progress --title="MD5sum" --text="Calculating SHA-1 for:\n${file##*/}" --percentage=0 --auto-close </tmp/checksum_fifo;

# If Cancel is clicked
if [ $? = 1 ];then
# Kill the sum process
kill $PVPID;
# Removes the tmp file and the pipe
rm $sum_temp;
rm /tmp/checksum_fifo
# Kill off this app
killall checksum;

fi;
# Removes the pipe file
rm /tmp/checksum_fifo ) &
ZENPID=$!

   #Wait until progressbar process finishes
   wait $ZENPID
   
    #Displays results
    sum=`cat $sum_temp`
    zenity --info --title="SHA-1" --text="SHA-1: $sum\nFile :    ${file##*/}" --no-wrap

    #Cleanup
    rm $sum_temp
    exit 0
fi

echo $selection | grep "SHA-224" > /dev/null
if [ $? = 0 ];then
   # Creates a subshell and sends progress to the named pipe
   ( pv -n "$file" | sha224sum  2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) ) 2>/tmp/checksum_fifo &
PVPID=$!

    # Creates a subshell and reads progress from the named pipe
   ( zenity --progress --title="MD5sum" --text="Calculating SHA-224 for:\n${file##*/}" --percentage=0 --auto-close </tmp/checksum_fifo;

# If Cancel is clicked
if [ $? = 1 ];then
# Kill the sum process
kill $PVPID;
# Removes the tmp file and the pipe
rm $sum_temp;
rm /tmp/checksum_fifo
# Kill off this app
killall checksum;

fi;
# Removes the pipe file
rm /tmp/checksum_fifo ) &
ZENPID=$!

   #Wait until progressbar process finishes
   wait $ZENPID
   
    #Displays results
    sum=`cat $sum_temp`
    zenity --info --title="SHA-224" --text="SHA-224 : $sum\nFile :         ${file##*/}" --no-wrap

    #Cleanup
    rm $sum_temp
    exit 0
fi

echo $selection | grep "SHA-256" > /dev/null
if [ $? = 0 ];then
    # Creates a subshell and sends progress to the named pipe
   ( pv -n "$file" | sha256sum 2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) ) 2>/tmp/checksum_fifo &
PVPID=$!

    # Creates a subshell and reads progress from the named pipe
   ( zenity --progress --title="MD5sum" --text="Calculating SHA-256 for:\n${file##*/}" --percentage=0 --auto-close </tmp/checksum_fifo;

# If Cancel is clicked
if [ $? = 1 ];then
# Kill the sum process
kill $PVPID;
# Removes the tmp file and the pipe
rm $sum_temp;
rm /tmp/checksum_fifo
# Kill off this app
killall checksum;

fi;
# Removes the pipe file
rm /tmp/checksum_fifo ) &
ZENPID=$!

   #Wait until progressbar process finishes
   wait $ZENPID
   
    #Displays results
    sum=`cat $sum_temp`
    zenity --info --title="SHA-256" --text="SHA-256 : $sum\nFile :          ${file##*/}" --no-wrap

    #Cleanup
    rm $sum_temp
    exit 0
fi

echo $selection | grep "SHA-384" > /dev/null
if [ $? = 0 ];then
    # Creates a subshell and sends progress to the named pipe
   ( pv -n "$file" | sha384sum 2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) ) 2>/tmp/checksum_fifo &
PVPID=$!

    # Creates a subshell and reads progress from the named pipe
   ( zenity --progress --title="MD5sum" --text="Calculating SHA-384 for:\n${file##*/}" --percentage=0 --auto-close </tmp/checksum_fifo;

# If Cancel is clicked
if [ $? = 1 ];then
# Kill the sum process
kill $PVPID;
# Removes the tmp file and the pipe
rm $sum_temp;
rm /tmp/checksum_fifo
# Kill off this app
killall checksum;

fi;
# Removes the pipe file
rm /tmp/checksum_fifo ) &
ZENPID=$!

   #Wait until progressbar process finishes
   wait $ZENPID
   
    #Displays results
    sum=`cat $sum_temp`
    zenity --info --title="SHA-384" --text="SHA-384 : $sum\nFile :         ${file##*/}" --no-wrap

    #Cleanup
    rm $sum_temp
    exit 0
fi

echo $selection | grep "SHA-512" > /dev/null
if [ $? = 0 ];then
    # Creates a subshell and sends progress to the named pipe
   ( pv -n "$file" | sha512sum 2>&1 | tee >(cut -d ' ' -f1 > $sum_temp) ) 2>/tmp/checksum_fifo &
PVPID=$!

    # Creates a subshell and reads progress from the named pipe
   ( zenity --progress --title="MD5sum" --text="Calculating SHA-512 for:\n${file##*/}" --percentage=0 --auto-close </tmp/checksum_fifo;

# If Cancel is clicked
if [ $? = 1 ];then
# Kill the sum process
kill $PVPID;
# Removes the tmp file and the pipe
rm $sum_temp;
rm /tmp/checksum_fifo
# Kill off this app
killall checksum;

fi;
# Removes the pipe file
rm /tmp/checksum_fifo ) &
ZENPID=$!

   #Wait until progressbar process finishes
   wait $ZENPID
   
    #Displays results
    sum=`cat $sum_temp`
    zenity --info --title="SHA-512" --text="SHA-512 : $sum\nFile :           ${file##*/}" --no-wrap

    #Cleanup
    rm $sum_temp
    exit 0
fi

Cheers  :)