Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash -
- # ---------------------------------------------------------------------------
- # tomato -
- # Copyright 2018, Scott Bicknell [email protected]
- # 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 3 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 at <http://www.gnu.org/licenses/> for
- # more details.
- # Usage: tomato [-h|--help]
- # Revision history:
- # 2017-05-28 Created by new_script ver. 3.3
- # ---------------------------------------------------------------------------
- PATH='/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/home/sbicknell/.local/bin:/home/sbicknell/bin'
- # =============================================================================
- # Debugging assistance
- # =============================================================================
- set -euo pipefail
- IFS=$'\n\t'
- # =============================================================================
- # Constants
- # =============================================================================
- declare -r PROGNAME=${0##*/} # program filename
- declare -r VERSION="0.1" # program version number
- if [[ -d $HOME/tmp ]]; then
- declare -r TMPDIR="$HOME/tmp"
- else
- declare -r TMPDIR='/tmp'
- fi
- # =============================================================================
- # Parse configuration
- # =============================================================================
- # source configuration file if it exists. Document expected values here
- if [[ -f $HOME/.${PROGNAME}rc ]]; then
- # shellcheck source=/home/sbicknell/.bash-template.shrc
- source "$HOME/.${PROGNAME}rc"
- fi
- # =============================================================================
- # Set command line option parser
- # =============================================================================
- # Test for GNU getopt, which will return '4'. All others will return 0 and
- # output '--'. Use GNU getopt or bash getopts. This is used by the usage()
- # and help() functions and by the option parsing code to determine what
- # options to enable and what help text to display after determining which
- # parser to use.
- set +e
- if ! getopt -T >/dev/null 2>&1; then
- parser='getopt'
- else
- parser='getopts'
- fi
- set -e
- # =============================================================================
- # Function definitions
- # =============================================================================
- temp_file() { # Create temporary files. Automatically deleted at exit
- set +e
- tmpfile=$(mktemp "$TMPDIR/$PROGNAME.$RANDOM.$$.XXXXXX") ||
- error_exit "creating temporary file failed"
- set -e
- exec 3>"$tmpfile"
- rm "$tmpfile"
- }
- lock_file() { # Create a lock file
- set +e
- mkdir -p "$TMPDIR/$PROGNAME" || error_exit "$PROGNAME already running"
- set -e
- }
- clean_up() { # Perform pre-exit housekeeping
- if [[ -d $TMPDIR/$PROGNAME ]]; then
- set +e
- if [[ -d $TMPDIR/$PROGNAME ]]; then
- rmdir "$TMPDIR/$PROGNAME" || error "removing $TMPDIR/$PROGNAME failed"
- fi
- set -e
- fi
- }
- message() { # Display messages to the user
- printf '%s: %s\n' "$PROGNAME" "$@"
- }
- error() { # Display messages to the user on standard error
- message "$@" >&2
- }
- # exit with an error message (default is "unspecified error") and a
- # customizable error code (default is 1).
- error_exit() {
- error "${1:-'unspecified error'}"
- clean_up
- exit "${2:-1}"
- }
- graceful_exit() {
- clean_up
- exit
- }
- version() {
- printf '%s %s\n' "$PROGNAME" "$VERSION"
- }
- usage() {
- if [[ $parser =~ ^getopt$ ]]; then # using GNU getopt
- echo -e "Usage:"
- echo -e " $PROGNAME -h|--help"
- echo -e " $PROGNAME -u|--usage"
- echo -e " $PROGNAME -v|--version"
- else # using bash getopts
- echo -e "Usage:"
- echo -e " $PROGNAME -h"
- echo -e " $PROGNAME -u"
- echo -e " $PROGNAME -v"
- fi
- }
- help_message() {
- if [[ $parser =~ ^getopt$ ]]; then # using GNU getopt
- # shellcheck disable=SC2119
- pg <<- EOF
- $PROGNAME ver. $VERSION
- Description:
- Program description.
- $(usage)
- Options:
- -h, --help Display this help message and exit.
- -u, --usage Display a shorter usage message and exit.
- -v, --version Display version information and exit.
- EOF
- return
- else
- # shellcheck disable=SC2119
- pg <<- EOF
- $PROGNAME ver. $VERSION
- Description:
- Program description.
- $(usage)
- Options:
- -h Display this help message and exit.
- -u Display a shorter usage message and exit.
- -v Display version information and exit.
- EOF
- return
- fi
- }
- #======================================================================
- # Format a file (or standard input) and display it or page it if
- # necessary
- # pg [-n] [file]
- # -n add line numbers to output
- #======================================================================
- # shellcheck disable=SC2120
- pg () {
- local ncols=0 # columns used for line numbering
- set +u
- local -r promptLines=$(echo -e "$PS1" | wc -l) # number of lines taken by PS1 prompt
- set -u
- # shellcheck disable=SC2154
- {
- local -A num
- num[cat]='' # parameter for turning on line numbering in cat (-n)
- num[less]='' # parameter for turning on line numbering in less (-N)
- }
- # capture standard input
- # huge files can, of course, fill all available memory
- while IFS='' read -r -t 0.1 line; do
- if ! [[ -v pipeFile ]]; then
- if [[ "${1:-}" = '-n' ]]; then
- ncols=8
- fi
- local -a pipeFile # array of lines from piped file
- local inc # amount to increment lineCount each pass through loop
- local lineCount=0 # total number of formatted lines of output
- fi
- # add current text line to list of lines, determine how many formatted lines
- # will result from it, and increment the total number of lines by that many
- pipeFile=( "${pipeFile[@]}" "$line" )
- inc=$(fmt -s -w $(( COLUMNS - ncols )) <<< "$line" | wc -l)
- lineCount=$(( lineCount + inc ))
- done
- # set up line numbering
- if [[ "${1:-}" = '-n' ]]; then
- ncols=8
- num[cat]='-n' # parameter for turning on line numbering in cat
- num[less]='-N' # parameter for turning on line numbering in less
- shift
- fi
- # if taking input from a file
- if [[ $# -gt 0 ]]; then # is there a file names to process?
- if [[ -f "${1:-}" ]]; then # and is it a regular file?
- # format file and feed it to either less or cat
- fmt -s -w $(( COLUMNS - ncols )) "${1:-}" |
- if [[ $(fmt -s -w $(( COLUMNS - ncols )) "${1:-}" | wc -l) \
- -gt $(( LINES - promptLines )) ]]; then
- set +u
- command less -R ${num[less]}
- set -u
- else
- set +u
- command cat ${num[cat]}
- set -u
- fi
- elif [[ -d "${1:-}" ]]; then
- printf '%s: %s: Is a directory\n' 'pg' "${1:-}" >&2
- else
- printf '%s: %s: No such file or directory\n' 'pg' "${1:-}" >&2
- fi
- elif [[ -v pipeFile ]]; then # taking input from standard input
- for line in "${pipeFile[@]}"; do
- echo "$line"
- done |
- fmt -s -w $(( COLUMNS - ncols )) |
- if [[ lineCount -gt $(( LINES - promptLines )) ]]; then
- set +u
- command less -R ${num[less]}
- set -u
- elif [[ lineCount -gt 0 ]]; then
- set +u
- command cat ${num[cat]}
- set -u
- else
- :
- fi
- fi
- }
- # =============================================================================
- # Exception handlers
- # =============================================================================
- signal_exit() { # Handle trapped signals
- case ${1:-} in
- INT)
- error_exit "Program interrupted by user"
- ;;
- QUIT)
- error_exit "Exiting..."
- ;;
- TERM)
- error_exit "Program terminated"
- ;;
- HUP)
- error_exit "Controlling process died"
- ;;
- *)
- error_exit "Terminating on ${1:-} signal"
- ;;
- esac
- }
- # Trap signals
- trap "signal_exit TERM" TERM HUP
- trap "signal_exit INT" INT
- # =============================================================================
- # Parse command line arguments
- # =============================================================================
- if [[ $parser =~ ^getopt$ ]]; then
- #while [[ -n $1 ]]; do
- # case $1 in
- # --help)
- # help_message
- # graceful_exit
- # ;;
- # --*)
- # usage
- # error_exit "Unknown option $1"
- # ;;
- # -[A-Za-z])
- # break
- # ;;
- # *)
- # echo "Argument $1 to process..."
- # ;;
- # esac
- # shift
- #done
- #
- # Follow short options with : to indicate required parameters and :: to
- # indicate optional parameters. Optional arguments to short options cannot
- # have any white space separating them from the option. Short options that
- # do not have required or optional arguments may be strung together after a
- # single - character. Long options with optional arguments must have an
- # equal sign separating them from the option name without white space.
- # Otherwise, required arguments may be separated from the long option name
- # with an equal sign or whitespace. Separate long options with commas in the
- # optstring of the optarg command line. '--' is added to the end of the
- # parsed options to indicate the end of command line options and arguments and
- # is expected to be handled by a '--' case in the option-parsing section of
- # code. It should include a shift followed by a break statement.
- #
- # case "$1" in
- # '-c'|'--c-long') # This has an optional argument
- # case "$2" in
- # '')
- # echo 'Option c, no argument'
- # ;;
- # *)
- # echo 'Option c, argument '$2'"
- # ;;
- # esac
- # shift 2
- # continue
- # ;;
- # '--') # end of argument list
- # shift
- # break
- # ;;
- # *) # if we are here then optarg had an internal error
- # echo 'Internal error!' >&2
- # exit 1
- # ;;
- # esac
- set +e
- temp=$(getopt -o 'huv' --long 'help,usage,version' -n "$PROGNAME" -- "$@")
- set -e
- case "$?" in
- 1) # unspecified arguments encountered
- error_exit 'usage error (use -h for help)'
- ;;
- 2) # getopt command line syntax error
- error_exit "getopt usage error (use 'man getopt' for help)"
- ;;
- 3) # getopt runtime error
- error_exit 'getopt internal error'
- ;;
- esac
- eval set -- "$temp"
- unset temp
- while true; do
- case "${1:-}" in
- '-h'|'--help')
- help_message
- # shift
- # continue
- graceful_exit
- ;;
- '-u'|'--usage')
- usage
- # shift
- # continue
- graceful_exit
- ;;
- '-v'|'--version')
- version
- # shift
- # continue
- graceful_exit
- ;;
- '--') # end of argument list
- shift
- break
- ;;
- esac
- done
- else # use getopts
- # parse command-line
- set +e
- while getopts ":huv" opt; do
- case "$opt" in
- h) # Display long help message
- set -e
- help_message
- graceful_exit
- ;;
- u) # Display short usage message
- set -e
- usage
- graceful_exit
- ;;
- v) # Display version
- set -e
- version
- graceful_exit
- ;;
- \?) # Handle invalid options
- set -e
- error_exit "invalid option: -$OPTARG"
- ;;
- :) # Handle missing option arguments
- set -e
- error_exit "option -$OPTARG requires an argument."
- ;;
- esac
- done
- shift $(( OPTIND - 1 ))
- set -e
- fi
- # either tell another instance to quit or look for a quit message
- cd "$TMPDIR"
- if [[ -p tomato ]]; then
- echo 'quit' > tomato && graceful_exit
- fi
- mkfifo tomato
- {
- until read -r; do
- sleep 1
- done < tomato
- rm tomato
- kdialog --title="${PROGNAME^}" --icon='org.kde.plasma.timer' \
- --passivepopup "Stopping tomato timer" &
- killall "$PROGNAME"
- } &
- # tomato timer workflow
- kdialog --title="${PROGNAME^}" --icon='org.kde.plasma.timer' \
- --passivepopup 'Starting tomato timer. Start working' &
- declare sessions=0
- while true; do
- sleep 25m
- sessions=$(( sessions + 1 ))
- if [[ $sessions -lt 4 ]]; then
- kdialog --title="${PROGNAME^}" --icon='org.kde.plasma.timer' \
- --passivepopup 'Take a 5-minute break' &
- sleep 5m
- else
- sessions=0
- kdialog --title="${PROGNAME^}" --icon='org.kde.plasma.timer' \
- --passivepopup 'Take a 15-minute break' &
- sleep 15m
- fi
- kdialog --title="${PROGNAME^}" --icon='org.kde.plasma.timer' \
- --passivepopup 'Get back to work' &
- done
- graceful_exit
- # vim: set tabstop=8 softtabstop=4 shiftwidth=4 noexpandtab number relativenumber:
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement