
  # -------------------------------------------------------------------------------------------------------------------------  #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #           File Name              :  Cron_start_stop.r                                                                      #
  #           Last Updated Funclist  :  18 Feb 2014, 11:56 AM (Tuesday)                                                        #
  #                                                                                                                            #
  #           Author Name            :  Rick Saporta                                                                           #
  #           Author Email           :  RickSaporta@gmail.com                                                                  #
  #           Author URL             :  www.github.com/rsaporta                                                                #
  #                                                                                                                            #
  #           Packages Called        :  NA                                                                                     #
  #           Packages Used via NS   :  NA                                                                                     #
  #                                                                                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #   startListener      ( py.file=getOption("crontab.py.file"), freq=30                                                       #
  #                        , units=c("Seconds", "Minutes", "Hours"), turn.off.crons.email.logs=TRUE                            #
  #                        , python=system("which python", TRUE), ignore.missing=FALSE, verbose=TRUE )                         #
  #   stopListener       ( py.file=getOption("crontab.py.file"), python=system("which python", TRUE), force=FALSE              #
  #                        , verbose=TRUE )                                                                                    #
  #   makeCronSchedule   ( seconds=30, minutes=Inf, hours=Inf, days=Inf, Month=Inf, showWarnings=TRUE )                        #
  #   showCrontabs       ( cron=system("crontab -l", intern=TRUE), n=30, pre="\t", output=FALSE )                              #
  #                                                                                                                            #
  #                                                                                                                            #
  #                                                     <END FUNCS>                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  # -------------------------------------------------------------------------------------------------------------------------  #


##  Set this option to  '/path/to/thisfile/RboxRelay_parse.py'
options(crontab.py.file='~/git/misc/rscripts/utils/notify/RboxRelay_Parse.py')


startListener <- function(py.file=getOption("crontab.py.file"), freq=30, units=c("Seconds", "Minutes", "Hours")
                          , turn.off.crons.email.logs=TRUE, python=system("which python", TRUE)
                          , ignore.missing=FALSE
                          , verbose=TRUE) {

  if (!file.exists(python))
    stop("Python does not exist")

  if (!file.exists(py.file) && !ignore.missing) 
    stop("The given script file, '", py.file, "' could not be found. To set the crontab anyway,\nrerun this command with 'ignore.missing=TRUE'")

  ## expand out any "~/"
  py.file <- path.expand(py.file)

  cmd <- sprintf("crontab -l | grep '%s\\b'", py.file)
  current <- suppressWarnings(system(cmd, intern=TRUE))

  # We expect current to be empty, meaning the job is not yet set
  if (length(current)) {
    verboseMsg(verbose, "Crontab had already been previously set to run the script\n  '", py.file ,"'\nBelow are the current settings\n\n\t", showCrontabs(cron=current), time=FALSE)
    return(invisible(FALSE))
  } 

  ## ELSE
  log <- ifelse(turn.off.crons.email.logs, ">/dev/null 2>&1", "")
  cron.cmd <- paste(python, py.file, log)

  sched <- makeCronSchedule(showWarnings=FALSE)

  tmp.file <- format(Sys.time(), format="%Y%m%d_%H%M%S")
  tmp.file <- paste0("tmp_crfile_", tmp.file, ".txt")

  ## Note, 'sched' can produce more than one item, so must collect in c() then collapse
  cmd <- paste(c(
            #eg:  crontab -l > $FILENAME
            sprintf("crontab -l > %s", tmp.file)
             #eg:  echo "* * * * * * $CMD" >> $FILENAME
             #eg:  echo "* * * * * * sleep 30; $CMD" >> $FILENAME
          , sprintf('echo "%s %s" >> %s', sched, cron.cmd, tmp.file)
             #eg:  crontab - < $FILENAME && rm $FILENAME
          , sprintf("crontab - < %s && rm %s", tmp.file, tmp.file)
          ), collapse="\n")

  verboseMsg(verbose, "Command being run is:\n\n", cmd, "\n", time=FALSE)
  ret <- system(cmd, intern=TRUE)

  cron <- system("crontab -l", intern=TRUE)
  verboseMsg(verbose, "Crontab has now been set for\n  '", py.file ,"'\n\nTasks set to run include :\n", paste(rep("-", 25), collapse=""), "\n", showCrontabs(n=30), time=FALSE)

  return(invisible(TRUE))
}

stopListener <- function(py.file=getOption("crontab.py.file")
                        , python=system("which python", TRUE)
                        , force=FALSE
                        , verbose=TRUE) {

  ## expand out any "~/"
  py.file <- path.expand(py.file)

  ## Match all lines containing the given py.file. 
  cmd.pos <- sprintf("crontab -l | grep '%s\\b'", py.file)
  ## The output of this command is what will be piped back in to crontab. Defining it here for clear context. 
  cmd.neg <- sprintf("crontab -l | grep -v '%s\\b'", py.file)

  ## suppressing warnings, because throws exit status 1 if no warning. 
  match.pos <- suppressWarnings(system(cmd.pos, TRUE))


  ## ERROR CHECK -- no real reason why these are not all true
  ##    stopifnot(  identical(sort(c(match.pos, match.neg)), sort(full))  )

  if (!length(match.pos))  {
    verboseMsg(verbose, "The script '", py.file, "' was not present in crontab. Nothing to remove", sep="", time=FALSE)
    verboseMsg(verbose, "\ncrontab is: \n\n", showCrontabs(), sep="", time=FALSE)
    return(invisible(FALSE))
  }  

  ## ELSE

  if (!force) {
    msg <- paste0("The following lines will be removed\n\n", showCrontabs(match.pos), "\n\nContinue removing [Yes / No]? > ")
    confirm <- readline(msg)
    
    if (!isYes(confirm)) {
      message("No changes were made to crontab")
      return(invisible(FALSE))
    }
  }

  ## if reached this point then either 'force' was TRUE or 'confirm' was YES
  ##   therefore, replace the crontab jobs with everything except the matched rows
  cmd.rm <- sprintf("%s | crontab", cmd.neg) 
  verboseMsg(verbose, "Executing the following command:\n\n", cmd.rm, "\n", time=FALSE)

  ## Execute. 
  caught <- system(cmd.rm, intern=TRUE)

  verboseMsg(verbose, "Crontab has been updated. Current standing is: \n\n", showCrontabs(), "\n", time=FALSE)

  ## caught should be an empty string
  ret <- identical(caught, character())
  return(invisible(ret))
}


makeCronSchedule <- function(seconds=30, minutes=Inf, hours=Inf, days=Inf, Month=Inf, showWarnings=TRUE) {
  if (showWarnings)
    warning("This function is not yet implemented.  Can only return every 30 seconds")

  sched <- c("* * * * *", "* * * * * sleep 30;")

  return(sched)
}

showCrontabs <- function(cron=system("crontab -l", intern=TRUE), n=30, pre="\t", output=FALSE) {
## TODO:  The intention of this function is to read is to take a crontab line and
## convert it to a human readable table. (including interpretting any use of 'sleep x;')
## Currently, this function simply spits out the same output, perhaps cropping some lines in the middle

  ## Input check
  if (n < 0)
    stop ("n should be a positive integer")


  if (length(cron) <= n+1) {
    ret <- paste(pre, cron, collapse="\n")
  } else {
    n.2 <- floor(n/2)
    remd <- sprintf("          [......     %i lines removed     ......]", length(cron)-n)
    ret <- paste(pre, c(head(cron, n.2), remd, tail(cron, n-n.2)), collapse="\n")
  }

  if (output) 
    cat(ret)

  return(ret)
}




##
##  SHELL EQUIVALENT
##
## 

#  if [ $NO_EMAIL_CRON_LOG = true ]
#    then 
#      LOG=">/dev/null 2>&1"
#    else
#      LOG=""
#  fi
#  
#  CMD="$PYTHON $SCRIPT $LOG"
#  
#  # touch $FILENAME
#  crontab -l > $FILENAME
#  echo "* * * * * * $CMD" >> $FILENAME
#  echo "* * * * * * sleep 28; $CMD" >> $FILENAME
#  crontab - < $FILENAME && rm $FILENAME


## If on a Mac, launch startListener()
if (identical(Sys.info()[['sysname']], "Darwin"))
  try(startListener('/Users/rsaporta/git/misc/rscripts/utils/notify/RboxRelay_Parse.py', verbose=FALSE))

