feat: list reads alarms, and _format_time for human-readable dates
This commit is contained in:
parent
47fe849e9f
commit
97e5dcbac4
2 changed files with 101 additions and 3 deletions
81
nag
81
nag
|
|
@ -502,6 +502,55 @@ _get_alarm_field() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Usage:
|
||||||
|
# _format_time <timestamp>
|
||||||
|
#
|
||||||
|
# Description:
|
||||||
|
# Format a unix timestamp for display.
|
||||||
|
# Time: dots for minutes (3.30pm), omit .00 (3pm).
|
||||||
|
# Date: Today / Tomorrow / day-of-week within 6 days /
|
||||||
|
# Next <day> within 13 days / Mon Dec 25 beyond that.
|
||||||
|
_format_time() {
|
||||||
|
local _timestamp="${1}"
|
||||||
|
|
||||||
|
# Format time: drop .00, use dots for minutes.
|
||||||
|
local _hour _minute _ampm _time_fmt
|
||||||
|
_hour="$(date -d "@${_timestamp}" "+%-I")"
|
||||||
|
_minute="$(date -d "@${_timestamp}" "+%M")"
|
||||||
|
_ampm="$(date -d "@${_timestamp}" "+%p" | tr '[:upper:]' '[:lower:]')"
|
||||||
|
if [[ "${_minute}" == "00" ]]
|
||||||
|
then
|
||||||
|
_time_fmt="${_hour}${_ampm}"
|
||||||
|
else
|
||||||
|
_time_fmt="${_hour}.${_minute}${_ampm}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Format date prefix.
|
||||||
|
local _alarm_date _today _days_away
|
||||||
|
_alarm_date="$(date -d "@${_timestamp}" +%Y-%m-%d)"
|
||||||
|
_today="$(date +%Y-%m-%d)"
|
||||||
|
_days_away=$(( ( $(date -d "${_alarm_date}" +%s) - $(date -d "${_today}" +%s) ) / 86400 ))
|
||||||
|
|
||||||
|
local _date_prefix
|
||||||
|
if (( _days_away == 0 ))
|
||||||
|
then
|
||||||
|
_date_prefix="Today"
|
||||||
|
elif (( _days_away == 1 ))
|
||||||
|
then
|
||||||
|
_date_prefix="Tomorrow"
|
||||||
|
elif (( _days_away <= 6 ))
|
||||||
|
then
|
||||||
|
_date_prefix="$(date -d "@${_timestamp}" "+%A")"
|
||||||
|
elif (( _days_away <= 13 ))
|
||||||
|
then
|
||||||
|
_date_prefix="Next $(date -d "@${_timestamp}" "+%A")"
|
||||||
|
else
|
||||||
|
_date_prefix="$(date -d "@${_timestamp}" "+%a %b %-d")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "%s, %s" "${_date_prefix}" "${_time_fmt}"
|
||||||
|
}
|
||||||
|
|
||||||
# Usage:
|
# Usage:
|
||||||
# _parse_time <time-string>
|
# _parse_time <time-string>
|
||||||
#
|
#
|
||||||
|
|
@ -652,6 +701,36 @@ list() {
|
||||||
printf "Nothing to nag about.\\n"
|
printf "Nothing to nag about.\\n"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
_read_alarms
|
||||||
|
|
||||||
|
# Sort alarms by timestamp (field 2).
|
||||||
|
local -a _sorted
|
||||||
|
IFS=$'\n' _sorted=($(printf "%s\n" "${_ALARMS[@]}" | sort -t$'\t' -k2 -n))
|
||||||
|
IFS=$'\n\t'
|
||||||
|
|
||||||
|
local _line
|
||||||
|
for _line in "${_sorted[@]}"
|
||||||
|
do
|
||||||
|
[[ -n "${_line}" ]] || continue
|
||||||
|
local _id _timestamp _rule _message _human_time _rule_display
|
||||||
|
|
||||||
|
_id="$(_get_alarm_field "${_line}" 1)"
|
||||||
|
_timestamp="$(_get_alarm_field "${_line}" 2)"
|
||||||
|
_rule="$(_get_alarm_field "${_line}" 3)"
|
||||||
|
_message="$(_get_alarm_field "${_line}" 4)"
|
||||||
|
|
||||||
|
_human_time="$(_format_time "${_timestamp}")"
|
||||||
|
|
||||||
|
if [[ -n "${_rule}" ]]
|
||||||
|
then
|
||||||
|
_rule_display="every ${_rule//,/, }, "
|
||||||
|
else
|
||||||
|
_rule_display=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "[%s] %s%s — %s\\n" "${_id}" "${_rule_display}" "${_human_time}" "${_message}"
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# at ##########################################################################
|
# at ##########################################################################
|
||||||
|
|
@ -693,7 +772,7 @@ at() {
|
||||||
_prompt_cron
|
_prompt_cron
|
||||||
|
|
||||||
local _human_time
|
local _human_time
|
||||||
_human_time="$(date -d "@${_timestamp}" "+%a %b %-d %-I:%M%p" | sed 's/AM/am/;s/PM/pm/')"
|
_human_time="$(_format_time "${_timestamp}")"
|
||||||
printf "[%s] %s — %s\\n" "${_id}" "${_human_time}" "${_message}"
|
printf "[%s] %s — %s\\n" "${_id}" "${_human_time}" "${_message}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,7 @@ load test_helper
|
||||||
@test "at creates a one-shot alarm" {
|
@test "at creates a one-shot alarm" {
|
||||||
run_nag at "tomorrow 3pm" "take a break"
|
run_nag at "tomorrow 3pm" "take a break"
|
||||||
[ "${status}" -eq 0 ]
|
[ "${status}" -eq 0 ]
|
||||||
[[ "${output}" =~ "[1]" ]]
|
[[ "${output}" =~ "[1] Tomorrow, 3pm — take a break" ]]
|
||||||
[[ "${output}" =~ "take a break" ]]
|
|
||||||
[ -f "${NAG_PATH}" ]
|
[ -f "${NAG_PATH}" ]
|
||||||
[ "$(wc -l < "${NAG_PATH}")" -eq 1 ]
|
[ "$(wc -l < "${NAG_PATH}")" -eq 1 ]
|
||||||
# Verify TSV structure: id<TAB>timestamp<TAB><TAB>message
|
# Verify TSV structure: id<TAB>timestamp<TAB><TAB>message
|
||||||
|
|
@ -88,3 +87,23 @@ load test_helper
|
||||||
[ "${status}" -eq 0 ]
|
[ "${status}" -eq 0 ]
|
||||||
[[ "${output}" =~ ^[0-9]+\.[0-9]+(_[a-zA-Z0-9]+)*$ ]]
|
[[ "${output}" =~ ^[0-9]+\.[0-9]+(_[a-zA-Z0-9]+)*$ ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "list shows formatted alarms with smart dates" {
|
||||||
|
run_nag at "tomorrow 3pm" "take a break"
|
||||||
|
run_nag
|
||||||
|
[ "${status}" -eq 0 ]
|
||||||
|
[[ "${output}" =~ "[1] Tomorrow, 3pm — take a break" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "list sorts alarms by time" {
|
||||||
|
run_nag at "tomorrow 3pm" "take a break"
|
||||||
|
run_nag at "tomorrow 9am" "standup"
|
||||||
|
run_nag
|
||||||
|
[ "${status}" -eq 0 ]
|
||||||
|
# 9am should come before 3pm in output.
|
||||||
|
local _first_line _second_line
|
||||||
|
_first_line="$(printf "%s\n" "${output}" | head -1)"
|
||||||
|
_second_line="$(printf "%s\n" "${output}" | sed -n '2p')"
|
||||||
|
[[ "${_first_line}" =~ "standup" ]]
|
||||||
|
[[ "${_second_line}" =~ "take a break" ]]
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue