294 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			294 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/bash -
 | |
| #===============================================================================
 | |
| #
 | |
| #         FILE: edit_tsu_blank
 | |
| #
 | |
| #        USAGE: ./edit_tsu_blank
 | |
| #
 | |
| #  DESCRIPTION: Edit a template for generating a tag and summary update email.
 | |
| #
 | |
| #      OPTIONS: ---
 | |
| # REQUIREMENTS: ---
 | |
| #         BUGS: ---
 | |
| #        NOTES: Now obsolete but retained for reference
 | |
| #       AUTHOR: Dave Morriss (djm), Dave.Morriss@gmail.com
 | |
| #      VERSION: 0.0.11
 | |
| #      CREATED: 2016-06-16 10:58:32
 | |
| #     REVISION: 2021-09-16 12:51:18
 | |
| #
 | |
| #===============================================================================
 | |
| 
 | |
| set -o nounset                              # Treat unset variables as an error
 | |
| 
 | |
| SCRIPT=${0##*/}
 | |
| 
 | |
| VERSION="0.0.11"
 | |
| 
 | |
| #
 | |
| # Load library functions
 | |
| #
 | |
| LIB="$HOME/bin/function_lib.sh"
 | |
| [ -e "$LIB" ] || { echo "$SCRIPT: Unable to source functions"; exit 1; }
 | |
| # shellcheck source=/home/cendjm/bin/function_lib.sh
 | |
| source "$LIB"
 | |
| 
 | |
| #===  FUNCTION  ================================================================
 | |
| #         NAME: find_work
 | |
| #  DESCRIPTION: Using 'grep' to count the number of un-edited lines in certain
 | |
| #               files make a list of their names and the number of edits for
 | |
| #               display in a 'select'.
 | |
| #   PARAMETERS: 1 - the name of the directory holding the files
 | |
| #               2 - the prefix of each file to identify them exactly
 | |
| #               3 - the name of an array to hold the list
 | |
| #      RETURNS: Nothing (uses a nameref argument)
 | |
| #===============================================================================
 | |
| find_work () {
 | |
|     local bd="${1:?Usage: find_work basedir prefix array}"
 | |
|     local pf="${2:?Usage: find_work basedir prefix array}"
 | |
|     local -n result="${3:?Usage: find_work basedir prefix array}"
 | |
|     local -a work
 | |
|     local elem count
 | |
| 
 | |
|     # Load all filenames into an array
 | |
|     mapfile -t work < <(grep -E -c "^(summary|tags): *$" "$bd/$pf"*[^~])
 | |
| 
 | |
|     # Add names containing work to the result array
 | |
|     for elem in "${work[@]}"; do
 | |
|         count="${elem##*:}"
 | |
|         if [[ $count -gt 0 ]]; then
 | |
|             printf -v count '%2d' "$count"
 | |
|             # Add colour and a reset for the yellow to be added later
 | |
|             result+=( "${elem%%:*}${reset} (${red}$count${reset} edits)" )
 | |
|         fi
 | |
|     done
 | |
| }
 | |
| 
 | |
| #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| #
 | |
| # Check arguments
 | |
| #
 | |
| if [[ $# -ne 0 ]]; then
 | |
|     echo "($SCRIPT Version $VERSION)"
 | |
|     echo "Usage: $SCRIPT"
 | |
|     exit
 | |
| fi
 | |
| 
 | |
| #
 | |
| # Directories and files
 | |
| #
 | |
| BASEDIR="$HOME/HPR/Database"
 | |
| TSU="$BASEDIR/tsu"
 | |
| VALIDATOR="$BASEDIR/validate_edits.awk"
 | |
| STATUSFILE="$BASEDIR/tag_summary_actions.csv"
 | |
| 
 | |
| PREFIX="tag_summary_updates_"
 | |
| 
 | |
| #
 | |
| # Sanity checks
 | |
| #
 | |
| [ -d "$BASEDIR" ] || { echo "Unable to find directory $BASEDIR"; exit 1; }
 | |
| [ -d "$TSU" ] || { echo "Unable to find directory $TSU"; exit 1; }
 | |
| 
 | |
| [ -e "$VALIDATOR" ] || { echo "File $VALIDATOR not found"; exit 1; }
 | |
| [ -e "$STATUSFILE" ] || { echo "File $STATUSFILE not found"; exit 1; }
 | |
| 
 | |
| #
 | |
| # Colour codes
 | |
| #
 | |
| define_colours
 | |
| 
 | |
| #
 | |
| # Using a function find which files have un-edited parts and save their names
 | |
| # and the number of edits in an array
 | |
| #
 | |
| declare -a choices
 | |
| find_work "$TSU" "${PREFIX}" choices
 | |
| 
 | |
| #
 | |
| # There could be no files with edits
 | |
| #
 | |
| if [[ ${#choices[@]} -eq 0 ]]; then
 | |
|     echo "${red}There are no files in need of editing!${reset}"
 | |
|     exit 1
 | |
| fi
 | |
| 
 | |
| #
 | |
| # Prompt for a choice from the array of files, removing the path from each
 | |
| # choice for readability. (Sadly 'select' changed its behaviour in Bash
 | |
| # 5 necessitating this). Add a yellow colour code before the resulting
 | |
| # filename; there's already a reset after the name.
 | |
| #
 | |
| PS3="Enter a number: "
 | |
| echo "Files in need of editing:"
 | |
| # select choice in "${choices[@]##*/}"
 | |
| select choice in "${choices[@]/${TSU}\//${yellow}}"
 | |
| do
 | |
|     break
 | |
| done
 | |
| 
 | |
| retval=$?
 | |
| if [[ $retval -ne 0 ]]; then
 | |
|     echo "${red}Selection aborted${reset}"
 | |
|     exit 1
 | |
| fi
 | |
| 
 | |
| #
 | |
| # Since we removed the full path in the 'select' list 'choice' contains that
 | |
| # name rather than the file path, so we need to make it such a path. We also
 | |
| # need to remove the string "(X edits)" from the end, and all the colour codes
 | |
| # we added earlier, then edit the file.
 | |
| #
 | |
| # We include Vim settings for the text width and filetype, and perform
 | |
| # a search for the next field that needs work (using 'silent!' to stop nasty
 | |
| # error messages if there's nothing that matches).
 | |
| #
 | |
| # We use an Awk script to determine if the file contains any shows which have
 | |
| # already been updated by another person. We use the file $STATUSFILE which
 | |
| # gets updated every time a report is generated.
 | |
| #
 | |
| 
 | |
| # Strip colour codes
 | |
| choice="${choice//$yellow/}"
 | |
| choice="${choice//$red/}"
 | |
| choice="${choice//$reset/}"
 | |
| 
 | |
| #
 | |
| # Run the Awk validator, and if OK edit the file, otherwise try to explain
 | |
| # what's wrong.
 | |
| #
 | |
| choice="$TSU/${choice%% *}"
 | |
| if awk --assign "csv=$STATUSFILE" -f "$VALIDATOR" "$choice"; then
 | |
|     csum1=$(md5sum < "$choice")
 | |
|     echo "Editing $choice"
 | |
|     vim +"set tw=100 ft=text" -c 'silent! /^\(summary\|tags\):\s*$'  "$choice"
 | |
|     csum2=$(md5sum < "$choice")
 | |
| 
 | |
|     if [[ $csum1 == "$csum2" ]]; then
 | |
|         echo "${yellow}No change was made${reset}"
 | |
|         exit
 | |
|     fi
 | |
| else
 | |
|     echo "${red}Errors found checking the file${reset}"
 | |
|     echo "Show(s) in this file have already been updated in the database."
 | |
|     echo "Somebody else has probably sent in an update for show(s) in the range."
 | |
|     echo "The file ${yellow}${choice}${reset}"
 | |
|     echo "has been edited automatically to comment out the updated show(s) and"
 | |
|     echo "is now ready for editing in the usual way (rerun this script to do it)."
 | |
|     echo "----"
 | |
|     echo "(This error may also be caused by an internal fault when running"
 | |
|     echo "awk. Check the file to be certain.)"
 | |
|     exit 1
 | |
| fi
 | |
| 
 | |
| #
 | |
| # Perform a check on what is now in the file looking for lines that are too
 | |
| # long or with a bad show number
 | |
| #
 | |
| echo "${yellow}Checking show numbers and lengths of summaries and tags${reset}"
 | |
| re="^([A-Za-z]+): *(.*) *$"
 | |
| count=0; errors=0
 | |
| while read -r line; do
 | |
|     ((count++))
 | |
|     if [[ $line =~ $re ]]; then
 | |
|         key="${BASH_REMATCH[1]}"
 | |
|         value="${BASH_REMATCH[2]}"
 | |
|         case $key in
 | |
|             show)
 | |
|                 if [[ ! $value =~ [0-9]{1,4} ]]; then
 | |
|                     ((errors++))
 | |
|                     printf '**Error**\n%02d: %s\n' "$count" "$line"
 | |
|                     echo "${blue}The show value must be a number (${#value})${reset}"
 | |
|                 fi
 | |
|                 ;;
 | |
| 
 | |
|             summary)
 | |
|                 if [[ ${#value} -gt 100 ]]; then
 | |
|                     ((errors++))
 | |
|                     printf '**Error**\n%02d: %s\n' "$count" "$line"
 | |
|                     echo "${blue}Value too long (${#value}, should be 100 max)${reset}"
 | |
|                 fi
 | |
|                 ;;
 | |
| 
 | |
|             tags)
 | |
|                 if [[ ${#value} -gt 200 ]]; then
 | |
|                     ((errors++))
 | |
|                     printf '**Error**\n%02d: %s\n' "$count" "$line"
 | |
|                     echo "${blue}Value too long (${#value}, should be 200 max)${reset}"
 | |
|                 fi
 | |
|                 ;;
 | |
| 
 | |
|             esac
 | |
|     fi
 | |
| done < "$choice"
 | |
| 
 | |
| #
 | |
| # Report a summary of the check
 | |
| #
 | |
| if [[ $errors -eq 0 ]]; then
 | |
|     echo "${green}No errors found${reset}"
 | |
| else
 | |
|     echo "${red}Found $errors errors${reset}"
 | |
| fi
 | |
| 
 | |
| #
 | |
| # Make temporary files and set traps to delete them
 | |
| #
 | |
| TMP1=$(mktemp) || {
 | |
|     echo "$SCRIPT: ${red}creation of temporary file failed!${reset}"
 | |
|     exit 1
 | |
| }
 | |
| trap 'cleanup_temp $TMP1' SIGHUP SIGINT SIGPIPE SIGTERM EXIT
 | |
| 
 | |
| #
 | |
| # Make a temporary Awk script
 | |
| #
 | |
| cat > "$TMP1" <<'ENDAWK'
 | |
| BEGIN {
 | |
|     shows = total = finished = todo = 0
 | |
| }
 | |
| 
 | |
| /^show:/          { shows++ }
 | |
| /^tags:\s*$/      { total++; todo++ }
 | |
| /^tags:\s*\S+/    { total++; finished++ }
 | |
| /^summary:\s*$/   { total++; todo++ }
 | |
| /^summary:\s*\S+/ { total++; finished++ }
 | |
| 
 | |
| END {
 | |
|     printf "shows=%d\n",shows
 | |
|     printf "total=%d\n",total
 | |
|     printf "finished=%d\n",finished
 | |
|     printf "todo=%d\n",todo
 | |
|     printf "left=%2.1f%%\n",(todo/total)*100
 | |
| }
 | |
| ENDAWK
 | |
| 
 | |
| #
 | |
| # Run the Awk script and make variables
 | |
| #
 | |
| declare shows total todo finished left
 | |
| eval "$(awk -f "$TMP1" "$choice")"
 | |
| 
 | |
| # todo="$(grep -E -c "^(summary|tags):\s*$" "$choice")"
 | |
| # total="$(grep -E -c "^(summary|tags):" "$choice")"
 | |
| # completed="$(grep -E -c "^(summary|tags): *\w+" "$choice")"
 | |
| 
 | |
| #
 | |
| # Is there still work to do on this file?
 | |
| #
 | |
| echo "${yellow}File statistics:${reset}"
 | |
| printf '%s%-19s %s%s\n' "${purple}" "Total shows:" "$shows" "${reset}"
 | |
| printf '%s%-19s %s%s\n' "${purple}" "Additions required:" "$total" "${reset}"
 | |
| printf '%s%-19s %s%s\n' "${purple}" "Already done:" "$finished" "${reset}"
 | |
| printf '%s%-19s %s%s\n' "${purple}" "Percent left:" "$left" "${reset}"
 | |
| case $todo in
 | |
|     0) echo "${green}All required work on this file has been done${reset}";;
 | |
|     1) echo "${red}There is still $todo tag/summary to add${reset}";;
 | |
|     *) echo "${red}There are still $todo tags/summaries to add${reset}"
 | |
| esac
 | |
| 
 | |
| exit
 | |
| 
 | |
| # vim: syntax=sh:ts=8:sw=4:ai:et:tw=78:fo=tcrqn21
 | |
| 
 |