summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbill-auger <mr.j.spam.me@gmail.com>2024-04-01 16:36:47 -0400
committerbill-auger <mr.j.spam.me@gmail.com>2024-04-01 23:08:03 -0400
commit56e8d72870e7e530143280f6cff1ba0e69b656dc (patch)
tree53dbb88e90f0eb555664426e6d5c0ccce56d6ba8
parenta2f78424496755ef3940e6aebeb24cd6edce83eb (diff)
refactor labs_change_detectordevelopment
-rwxr-xr-xlabs_change_detector118
-rwxr-xr-xtest-email/pbot-test-email.sh7
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