diff options
author | bill-auger <mr.j.spam.me@gmail.com> | 2024-04-01 16:36:47 -0400 |
---|---|---|
committer | bill-auger <mr.j.spam.me@gmail.com> | 2024-04-01 23:08:03 -0400 |
commit | 56e8d72870e7e530143280f6cff1ba0e69b656dc (patch) | |
tree | 53dbb88e90f0eb555664426e6d5c0ccce56d6ba8 | |
parent | a2f78424496755ef3940e6aebeb24cd6edce83eb (diff) |
refactor labs_change_detectordevelopment
-rwxr-xr-x | labs_change_detector | 118 | ||||
-rwxr-xr-x | test-email/pbot-test-email.sh | 7 |
2 files changed, 75 insertions, 50 deletions
diff --git a/labs_change_detector b/labs_change_detector index 0c5d72c..bdeedcc 100755 --- a/labs_change_detector +++ b/labs_change_detector @@ -30,6 +30,9 @@ readonly PBOT_DIR="$(realpath "$(dirname "$(basename $0)")")" readonly LOG_DIR="${PBOT_DIR}"/logs/current readonly LOG_FILE="${LOG_DIR}"/$( (( IS_TEST_MODE )) && echo test.log || echo main.log ) readonly PBOT_DIR_ERR_MSG="ERROR: LOG_FILE: '${LOG_FILE}' not writable" +readonly BUG_TRACKER_URL=https://labs.parabola.nu/issues/ +readonly FORUM_URL=https://labs.parabola.nu/boards/ +readonly BORKED_SUBJECT_RX='s|Subject: \[\([^_]\+\)_-_\([^_]\+\)_\(#[0-9]\+\)\]_|Subject: [\1 - \2 \3] |' # redmine weirdness # mimick lib/log.sh logging @@ -60,29 +63,32 @@ parse_email() local nick local activity local out_msg='' - local this_line_is_url=0 - local this_line_is_activity=0 + local this_line_is_url=0 # state-0->3 (forum) + local this_line_is_activity=0 # state-0->1 (tickets) local ticket_n - local this_line_is_change_msg=0 + local this_line_is_change_msg=0 # state-1->2 (tickets) local prev_state local next_state local assignee local file_deleted - local is_subject_change=0 + local is_subject=0 local dup_n - local this_line_is_metadata=0 - local borked_subject_rx='s|Subject: \[\([^_]\+\)_-_\([^_]\+\)_\(#[0-9]\+\)\]_|Subject: [\1 - \2 \3] |' # redmine weirdness + local this_line_is_metadata=0 # state-2->3 (tickets) + # parsing loop (state machine) while IFS='' read -r line do line=$(sed 's|=0D$||g' <<<${line}) # redmine weirdness line=$(sed 's|=28|(|g ; s|=29|)|g' <<<${line}) # redmine weirdness line=$(sed 's|[^r]=[0-9A-F]\{2\}||g' <<<${line}) # redmine weirdness line=$(sed 's|=?UTF-8?Q?||g' <<<${line}) # redmine weirdness line=$(sed 's|?=||g' <<<${line}) # redmine weirdness - line=$(sed "${borked_subject_rx}" <<<${line}) # redmine weirdness + line=$(sed "${BORKED_SUBJECT_RX}" <<<${line}) # redmine weirdness (( DEBUG )) && echo "line=${line}" >&2 + + ## state-0 (email headers) ## + case "${line}" in 'Message-ID: <'* ) # parse forum message_id # detect forum thread @@ -99,7 +105,7 @@ parse_email() # determine forum OP vs reply if [[ "${line}" =~ \<redmine\.message-([0-9]+\.[0-9]+)@ ]] then reference_id=${BASH_REMATCH[1]} - is_reply=$( [[ "${message_id}" != "${reference_id}" ]] && echo 1 || echo 0 ) + is_reply=$( [[ "${message_id}" != "${reference_id}" ]] ; echo $((!$?)) ) else continue # uninteresting for tickets fi @@ -133,6 +139,7 @@ parse_email() 'X-Redmine-Sender: '* ) # parse forum post nick # inject forum activity message + # n/a tickets (( is_forum )) || continue nick=${line##*: } @@ -144,13 +151,15 @@ parse_email() 'List-Id: <labs.parabola.nu>' ) # detect begin of forum thread URL or ticket activity (( IS_TEST_MODE )) && out_msg+="<LIST-ID>" - if (( is_forum )) then this_line_is_url=1 else this_line_is_activity=1 fi ;; + + ## state-1 (ticket change message) ## + 'Issue #'* ) # parse ticket#, activity, nick # detect begin of ticket state change # n/a forum threads @@ -207,7 +216,7 @@ parse_email() (( IS_TEST_MODE )) && out_msg+="<CHANGE>" - is_subject_change=1 + is_subject=1 ;; 'File '*' added'* ) # parse ticket attachment addition, if applicable @@ -265,6 +274,9 @@ parse_email() fi ;; + + ## state-2 (ticket meta-data) ## + '----------------------------------------') # detect begin/end of ticket metadata # n/a forum threads ! (( is_forum )) || continue @@ -280,55 +292,30 @@ parse_email() (( IS_TEST_MODE )) && out_msg+="<META>" - while true - do if [[ "${activity}" ]] # OP, description change, or comment - then out_msg+="${nick} ${activity} ticket ${ticket_n}" - activity='' - elif [[ "${next_state}" ]] # state changed - then out_msg+="${nick} changed the state of ticket ${ticket_n} to '${next_state}'" - next_state='' - elif [[ "${unassignee}" ]] # assignee changed - then out_msg+="${nick} re-assigned ticket ${ticket_n} from ${unassignee} to ${assignee}" - assignee='' ; unassignee='' ; - elif [[ "${assignee}" ]] # assignee set - then out_msg+="${nick} assigned ticket ${ticket_n} to ${assignee}" - assignee='' - elif (( is_subject_change )) # subject changed - then out_msg+="${nick} changed the subject of ticket ${ticket_n}" - is_subject_change=0 - elif [[ "${file_added}" ]] # attachment added - then out_msg+="${nick} added an attachment to ticket ${ticket_n}" - file_added='' - elif [[ "${file_deleted}" ]] # attachment deleted - then out_msg+="${nick} deleted an attachment from ticket ${ticket_n}" - file_deleted='' - elif [[ "${parent_n}" ]] # parented/re-parented - then out_msg+="${nick} parented ticket ${ticket_n} to ${parent_n}" - parent_n='' - elif [[ "${dup_n}" ]] # relation changed - then out_msg+="${nick} noted that ticket ${ticket_n} is a duplicate of ${dup_n}" - dup_n='' - else break - fi - nick=', and ' - done - out_msg+=" - ${tracker}/${concern} (${state}): ${subject}" - + # summarize the changes + out_msg+="$(change_msgs) - ${tracker}/${concern} (${state}): ${subject}" this_line_is_url=1 ;; - 'https://labs.parabola.nu/boards/'* ) # parse thread URL + + ## state-3 (URL and finalize) ## + + ${FORUM_URL}* ) # parse thread URL and finalize message (( IS_TEST_MODE )) && out_msg+="<URL>" (( this_line_is_url )) && out_msg+=" - <${line}>" && break ;; - 'https://labs.parabola.nu/issues/'* ) # parse ticket URL + ${BUG_TRACKER_URL}* ) # parse ticket URL and finalize message (( IS_TEST_MODE )) && out_msg+="<URL>" (( this_line_is_metadata )) && out_msg+=" - <${line}>" && break ;; + + ## state-0 (email headers) ## + *) # parse multi-line thread subject (( this_line_is_subject )) && subject+="${line}" - esac + ;; + esac done # suppress replies to rejected tickets @@ -341,9 +328,44 @@ parse_email() echo ${out_msg} } +change_msgs() +{ + local activity_msg="${activity} ticket ${ticket_n}" + local state_msg="changed the state of ticket ${ticket_n} to '${next_state}'" + local unassign_msg="re-assigned ticket ${ticket_n} from ${unassignee} to ${assignee}" + local assign_msg="assigned ticket ${ticket_n} to ${assignee}" + local subject_msg="changed the subject of ticket ${ticket_n}" + local added_msg="added an attachment to ticket ${ticket_n}" + local deleted_msg="deleted an attachment from ticket ${ticket_n}" + local parent_msg="parented ticket ${ticket_n} to ${parent_n}" + local dup_msg="noted that ticket ${ticket_n} is a duplicate of ${dup_n}" + local and_msg='' + + printf "${nick} " + while true + do [[ -n ${change_msg:-} ]] && and_msg=', and ' || and_msg='' + + if [[ "$activity" ]] ; then change_msg="${activity_msg}" ; activity='' ; # OP, description change, or comment + elif [[ "$next_state" ]] ; then change_msg="${state_msg}" ; next_state='' ; # state changed + elif [[ "$unassignee" ]] ; then change_msg="${unassign_msg}" ; unassignee='' ; # assignee changed + assignee='' ; + elif [[ "$assignee" ]] ; then change_msg="${assign_msg}" ; assignee='' ; # assignee set + elif (( is_subject )) ; then change_msg="${subject_msg}" ; is_subject=0 ; # subject changed + elif [[ "$file_added" ]] ; then change_msg="${added_msg}" ; file_added='' ; # attachment added + elif [[ "$file_deleted" ]] ; then change_msg="${deleted_msg}" ; file_deleted='' ; # attachment deleted + elif [[ "$parent_n" ]] ; then change_msg="${parent_msg}" ; parent_n='' ; # parented/re-parented + elif [[ "$dup_n" ]] ; then change_msg="${dup_msg}" ; dup_n='' ; # relation changed + else return + fi + + printf "${and_msg}${change_msg}" + done +} + handle_email() { - while read email_file ; do parse_email < "${email_file}" ; done | \ + + while read email_file ; do parse_email < "${email_file}" ; done | while read message ; do send_ipc_msg '0' "${message}" ; done ; } diff --git a/test-email/pbot-test-email.sh b/test-email/pbot-test-email.sh index a7e5c72..43986c5 100755 --- a/test-email/pbot-test-email.sh +++ b/test-email/pbot-test-email.sh @@ -20,7 +20,7 @@ # along with 'pbot'. If not, see <http://www.gnu.or -DBG_KEYID=105 +# DBG_KEYID=105 readonly PBOT_DIR="$(realpath "$(dirname "$(basename $0)")")" readonly TEST_DIR="${PBOT_DIR}"/test-email @@ -88,4 +88,7 @@ do email_file=${key/*_} echo "[${result}]: ${email_file}" [[ "${result}" == 'FAILED' ]] && echo -e " expected : ${expected}\n actual : ${actual}" done -(( ${#keys[*]} )) && cat ${LOG_FILE} 2> /dev/null || echo "nothing was tested" +if (( ${#keys[*]} )) +then echo -e "\nlog:\n$(cat ${LOG_FILE} 2> /dev/null)" +else echo "nothing was tested" +fi |