citadel

My dotfiles, scripts and nix configs
git clone git://jb55.com/citadel
Log | Files | Refs | README | LICENSE

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 }