long-running.bash (4655B)
1 # Copyright (c) 2008-2012 undistract-me developers. See LICENSE for details. 2 # 3 # Source this, and then run notify_when_long_running_commands_finish_install 4 # 5 # Relies on http://www.twistedmatrix.com/users/glyph/preexec.bash.txt 6 7 # Generate a notification for any command that takes longer than this amount 8 # of seconds to return to the shell. e.g. if LONG_RUNNING_COMMAND_TIMEOUT=10, 9 # then 'sleep 11' will always generate a notification. 10 11 # Default timeout is 10 seconds. 12 if [ -z "$LONG_RUNNING_COMMAND_TIMEOUT" ]; then 13 LONG_RUNNING_COMMAND_TIMEOUT=10 14 fi 15 16 # Default is not to play sound along with notification. (0 is false, non-zero is true.) 17 if [ -z "$UDM_PLAY_SOUND" ]; then 18 UDM_PLAY_SOUND=0 19 fi 20 21 # The pre-exec hook functionality is in a separate branch. 22 if [ -z "$LONG_RUNNING_PREEXEC_LOCATION" ]; then 23 LONG_RUNNING_PREEXEC_LOCATION=/usr/share/undistract-me/preexec.bash 24 fi 25 26 if [ ! -f "$LONG_RUNNING_PREEXEC_LOCATION" ]; then 27 LONG_RUNNING_PREEXEC_LOCATION="$( dirname "${BASH_SOURCE[0]}" )/preexec.bash" 28 fi 29 30 if [ -f "$LONG_RUNNING_PREEXEC_LOCATION" ]; then 31 . $LONG_RUNNING_PREEXEC_LOCATION 32 else 33 echo "Could not find preexec.bash" 34 fi 35 36 37 function notify_when_long_running_commands_finish_install() { 38 39 function get_now() { 40 local secs 41 if ! secs=$(printf "%(%s)T" -1 2> /dev/null) ; then 42 secs=$(\date +'%s') 43 fi 44 echo $secs 45 } 46 47 function active_window_id () { 48 if [[ -n $DISPLAY ]] ; then 49 xprop -root _NET_ACTIVE_WINDOW | awk '{print $5}' 50 return 51 fi 52 echo nowindowid 53 } 54 55 function sec_to_human () { 56 local H='' 57 local M='' 58 local S='' 59 60 local h=$(($1 / 3600)) 61 [ $h -gt 0 ] && H="${h} hour" && [ $h -gt 1 ] && H="${H}s" 62 63 local m=$((($1 / 60) % 60)) 64 [ $m -gt 0 ] && M=" ${m} min" && [ $m -gt 1 ] && M="${M}s" 65 66 local s=$(($1 % 60)) 67 [ $s -gt 0 ] && S=" ${s} sec" && [ $s -gt 1 ] && S="${S}s" 68 69 echo $H$M$S 70 } 71 72 function precmd () { 73 74 if [[ -n "$__udm_last_command_started" ]]; then 75 local now current_window 76 77 now=$(get_now) 78 current_window=$(active_window_id) 79 80 81 if [[ $current_window != $__udm_last_window ]] || 82 [[ ! -z "$IGNORE_WINDOW_CHECK" ]] || 83 [[ $current_window == "nowindowid" ]] ; then 84 echo "$__udm_last_window" > $HOME/var/cmd_last_window 85 local time_taken=$(( $now - $__udm_last_command_started )) 86 local longtimeout="$(((time_taken / 3) * 1000))" 87 local timeout="$(btcs -t 15000 $longtimeout min)" 88 local time_taken_human=$(sec_to_human $time_taken) 89 local appname=$(basename "${__udm_last_command%% *}") 90 if [[ $time_taken -gt $LONG_RUNNING_COMMAND_TIMEOUT ]] && 91 [[ -n $DISPLAY ]] && 92 [[ ! " $LONG_RUNNING_IGNORE_LIST " == *" $appname "* ]] ; then 93 local icon=check-mark 94 local urgency=normal 95 if [[ $__preexec_exit_status != 0 ]]; then 96 icon=cross-mark 97 fi 98 notify=$(command -v notify-send) 99 if [ -x "$notify" ]; then 100 $notify \ 101 -i $icon \ 102 -t $timeout \ 103 -u $urgency \ 104 "Command completed in $time_taken_human" \ 105 "$__udm_last_command" 106 if [[ "$UDM_PLAY_SOUND" != 0 ]]; then 107 paplay /usr/share/sounds/freedesktop/stereo/complete.oga 108 fi 109 else 110 echo -ne "\a" 111 fi 112 fi 113 if [[ -n $LONG_RUNNING_COMMAND_CUSTOM_TIMEOUT ]] && 114 [[ -n $LONG_RUNNING_COMMAND_CUSTOM ]] && 115 [[ $time_taken -gt $LONG_RUNNING_COMMAND_CUSTOM_TIMEOUT ]] && 116 [[ ! " $LONG_RUNNING_IGNORE_LIST " == *" $appname "* ]] ; then 117 # put in brackets to make it quiet 118 export __preexec_exit_status 119 ( $LONG_RUNNING_COMMAND_CUSTOM \ 120 "\"$__udm_last_command\" took $time_taken_human" & ) 121 fi 122 fi 123 fi 124 } 125 126 function preexec () { 127 # use __udm to avoid global name conflicts 128 __udm_last_command_started=$(get_now) 129 __udm_last_command=$(echo "$1") 130 __udm_last_window=$(active_window_id) 131 } 132 133 preexec_install 134 }