forked from HPR/hpr-tools
		
	
		
			
	
	
		
			294 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			294 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | #!/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 | ||
|  | 
 |