#!/bin/bash
#
# postpone {jobid} "{time to postpone}"
#
# A script to check if some job (identified by string jobid) has been
# recently run or if it should be postponed. This might be useful if a
# job/script runs e.g. every hour but should send out notifications only
# every some hours.

# Version 0.12 * 2008-06-27
# Copyright Andreas Schamanek <http://andreas.schamanek.net/>
# GPL licensed (see end of file) * Use at your own risk!

# Note: As the name of this script implies it returns 0 (true) if the
# named job is to be postponed (means the last logged run was less than
# $2 "time" ago). The script returns 1 (false) if the named job should
# run "now" (means it either has not been seen here before or the last
# logged run was more than $2 "time" ago).
#
# Example usage in a script which runs every hour but should send a mail
# only every 6 hours:
#   test postpone myscriptid "6 hours" || echo "foo" | mail root

# Script needs: sed, grep, tail, cut, date +%s (i.e. this should give 42:
#   echo $(( $(date -d "now + 42 secs" +%s) - $(date +%s) ))

USAGE="Usage  : postpone {jobid} \"time interval\"
Example: postpone foobar \"6 hours\""

# we need 2 parameters
test "/$1/" = '//' && { echo "$USAGE" >&2 ; exit 70 ; }
test "/$2/" = '//' && { echo "$USAGE" >&2 ; exit 70 ; }
test "/$3/" = '//' || { echo "$USAGE" >&2 ; exit 70 ; }

# assign values (and sanitize)
# jobid must not contain "special" characters 
JOBID=$(echo "$1"|sed -e 's/[^0-9a-zA-Z_%=#;:-]//g')
if [ "/$JOBID/" = '//' ] ; then
   echo "$USAGE" >&2
   echo "Note: jobid must not contain funny characters" >&2
   exit 71
fi
POSTPONE="$2"  # e.g. "6 hours" ... no checking is done

# file to store JOBID and time of last notification
# (format of $MYLOGFILE: jobid date; where date is +%Y-%m-%d\ %H:%M:%S)
# (remove or shorten this file from time to time or else it will grow 
# indefinitely ;)
MYLOGFILE=$HOME/postpone.cache
test -e $MYLOGFILE || touch $MYLOGFILE # if logfile does not exist yet
test -w $MYLOGFILE || { echo "$MYLOGFILE not writable" >&2 ; exit 83 ; }

# get time of last run (or none if there was none)
LASTRUN=$(grep "^$JOBID [0-9]" $MYLOGFILE | tail -1 | cut -d' ' -f2,3)

# there is only 1 case where we return 0 and do nothing else:
# that is when there was a previous run logged and POSTPONE time is not
# yet over
if [ "/$LASTRUN/" != '//' ] ; then
   # check time of last run
   # i.e. return 0 if stored date + POSTPONE is in future
   NOWSECONDS=$(date +%s)
   LASTRUNSECONDS=$(date -d "$LASTRUN" +%s)
   POSTPONESECONDS=$(date -d "now + $POSTPONE" +%s)
   POSTPONESECONDS=$((POSTPONESECONDS-NOWSECONDS))
   test $((LASTRUNSECONDS+POSTPONESECONDS)) -gt $NOWSECONDS && exit 0
fi

# in all other cases we return 1 and log the run
# write a note to logfile (comment this out if your script does the logging)
echo "$JOBID $(date +%Y-%m-%d\ %H:%M:%S)" >>$MYLOGFILE

exit 1

# License
#
# This script 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 script 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 script; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
# Boston, MA  02111-1307  USA

# History
#
# v0.12 2008-06-27 added license; published at http://wox.at/as/_/ ...
# v0.11 2007-11-09 fixed a bug of _date_ in newer versions, see
#       http://wox.at/as/_/blog:071030_date_is_not_date
# v0.1  2007-07-25 initial version


