234 lines
6.6 KiB
Bash
234 lines
6.6 KiB
Bash
# iCalendar modification wrapper
|
|
# - __edit
|
|
# - __new
|
|
# - __delete
|
|
# - __import_to_collection
|
|
# - __cancel_toggle
|
|
# - __tentative_toggle
|
|
# - __add_attachment
|
|
|
|
# Edit iCalendar file.
|
|
#
|
|
# @input $1: Start date/date-time
|
|
# @input $2: End date/date-time
|
|
# @input $3: Path to iCalendar file (relative to `$ROOT`)
|
|
__edit() {
|
|
start=$(__datetime_human_machine "$1")
|
|
end=$(__datetime_human_machine "$2")
|
|
fpath="$ROOT/$3"
|
|
location=$(awk -v field="LOCATION" "$AWK_GET" "$fpath" | tr -d "\n")
|
|
summary=$(awk -v field="SUMMARY" "$AWK_GET" "$fpath" | tr -d "\n")
|
|
description=$(awk -v field="DESCRIPTION" "$AWK_GET" "$fpath")
|
|
filetmp=$(mktemp --suffix='.md')
|
|
printf "::: |> %s\n::: <| %s\n" "$start" "$end" >"$filetmp"
|
|
if [ -n "$location" ]; then
|
|
printf "@ %s\n" "$location" >>"$filetmp"
|
|
fi
|
|
printf "# %s\n\n%s\n" "$summary" "$description" >>"$filetmp"
|
|
checksum=$(cksum "$filetmp")
|
|
$EDITOR "$filetmp" >/dev/tty
|
|
|
|
# Update only if changes are detected
|
|
if [ "$checksum" != "$(cksum "$filetmp")" ]; then
|
|
filenew="$filetmp.ics"
|
|
if awk "$AWK_UPDATE" "$filetmp" "$fpath" >"$filenew"; then
|
|
mv "$filenew" "$fpath"
|
|
if [ -n "${GIT:-}" ]; then
|
|
$GIT add "$fpath"
|
|
$GIT commit -q -m "Modified event '$(__summary_for_commit "$fpath") ...'" -- "$fpath"
|
|
fi
|
|
__refresh_data
|
|
else
|
|
rm -f "$filenew"
|
|
err "Failed to edit entry. Press <enter> to continue."
|
|
read -r tmp
|
|
fi
|
|
fi
|
|
rm "$filetmp"
|
|
}
|
|
|
|
# Generate new iCalendar file
|
|
#
|
|
# This function also sets the `$start` variable to the start of the new entry.
|
|
# On failure, start will be empty.
|
|
#
|
|
# If some start has been specified and the nanoseconds are not 0, we assume
|
|
# that the user entered "tomorrow" or something like that, and did not
|
|
# specify the time. So, we will use the `$DAY_START` time of that date.
|
|
# If the user specified a malformed date/date-time, we fail.
|
|
#
|
|
# @input $1 (optional): Date or datetime, defaults to today.
|
|
__new() {
|
|
collection=$(echo "$COLLECTION_LABELS" | tr ';' '\n' | awk '/./ {print}' | $FZF --margin="30%" --no-info --delimiter='=' --with-nth=2 --accept-nth=1)
|
|
fpath=""
|
|
while [ -f "$fpath" ] || [ -z "$fpath" ]; do
|
|
uuid=$($UUIDGEN)
|
|
fpath="$ROOT/$collection/$uuid.ics"
|
|
done
|
|
d="today $DAY_START"
|
|
if [ -n "${1:-}" ]; then
|
|
d="$1"
|
|
if [ "$(date -d "$1" +"%N")" -ne 0 ]; then
|
|
d="$d $DAY_START:00"
|
|
fi
|
|
fi
|
|
startsec=$(date -d "$d" +"%s")
|
|
endsec=$((startsec + 3600))
|
|
start=$(__datetime_human_machine "$startsec")
|
|
end=$(__datetime_human_machine "$endsec")
|
|
filetmp=$(mktemp --suffix='.md')
|
|
(
|
|
echo "::: |> $start"
|
|
echo "::: <| $end"
|
|
echo "@ <!-- write location here, optional line -->"
|
|
echo "# <!-- write summary here -->"
|
|
echo ""
|
|
) >"$filetmp"
|
|
checksum=$(cksum "$filetmp")
|
|
$EDITOR "$filetmp" >/dev/tty
|
|
|
|
# Update only if changes are detected
|
|
if [ "$checksum" != "$(cksum "$filetmp")" ]; then
|
|
filenew="$filetmp.ics"
|
|
if awk -v uid="$uuid" "$AWK_NEW" "$filetmp" >"$filenew"; then
|
|
mv "$filenew" "$fpath"
|
|
if [ -n "${GIT:-}" ]; then
|
|
$GIT add "$fpath"
|
|
$GIT commit -q -m "Added event '$(__summary_for_commit "$fpath") ...'" -- "$fpath"
|
|
fi
|
|
start=$(awk -v field="DTSTART" "$AWK_GET" "$fpath" | grep -o '[0-9]\{8\}')
|
|
else
|
|
rm -f "$filenew"
|
|
start=""
|
|
err "Failed to create new entry. Press <enter> to continue."
|
|
read -r tmp
|
|
fi
|
|
fi
|
|
rm "$filetmp"
|
|
}
|
|
|
|
# Delete iCalendar file
|
|
#
|
|
# @input $1: Path to iCalendar file, relative to `$ROOT`
|
|
__delete() {
|
|
fpath="$ROOT/$1"
|
|
summary=$(awk -v field="SUMMARY" "$AWK_GET" "$fpath")
|
|
while true; do
|
|
printf "Do you want to delete the entry with the title \"%s\"? (yes/no): " "$summary" >/dev/tty
|
|
read -r yn
|
|
case $yn in
|
|
"yes")
|
|
sfg="$(__summary_for_commit "$fpath")"
|
|
rm -v "$fpath"
|
|
if [ -n "${GIT:-}" ]; then
|
|
$GIT add "$fpath"
|
|
$GIT commit -q -m "Deleted event '$sfg ...'" -- "$fpath"
|
|
fi
|
|
break
|
|
;;
|
|
"no")
|
|
break
|
|
;;
|
|
*)
|
|
echo "Please answer \"yes\" or \"no\"." >/dev/tty
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
# Import iCalendar file to specified collection. The only modification made to
|
|
# the file is setting the UID.
|
|
#
|
|
# @input $1: path to iCalendar file
|
|
# @input $2: collection name
|
|
__import_to_collection() {
|
|
file="$1"
|
|
collection="$2"
|
|
fpath=""
|
|
while [ -f "$fpath" ] || [ -z "$fpath" ]; do
|
|
uuid=$($UUIDGEN)
|
|
fpath="$ROOT/$collection/$uuid.ics"
|
|
done
|
|
filetmp=$(mktemp)
|
|
awk -v field="UID" -v value="$uuid" "$AWK_SET" "$file" >"$filetmp"
|
|
mv "$filetmp" "$fpath"
|
|
if [ -n "${GIT:-}" ]; then
|
|
$GIT add "$fpath"
|
|
$GIT commit -q -m "Imported event '$(__summary_for_commit "$fpath") ...'" -- "$fpath"
|
|
fi
|
|
}
|
|
|
|
# Set status of appointment to CANCELLED or CONFIRMED (toggle)
|
|
#
|
|
# @input $1: path to iCalendar file
|
|
__cancel_toggle() {
|
|
fpath="$ROOT/$1"
|
|
status=$(awk -v field="STATUS" "$AWK_GET" "$fpath")
|
|
newstatus="CANCELLED"
|
|
if [ "${status:-}" = "$newstatus" ]; then
|
|
newstatus="CONFIRMED"
|
|
fi
|
|
filetmp=$(mktemp)
|
|
awk -v field="STATUS" -v value="$newstatus" "$AWK_SET" "$fpath" >"$filetmp"
|
|
mv "$filetmp" "$fpath"
|
|
if [ -n "${GIT:-}" ]; then
|
|
$GIT add "$fpath"
|
|
$GIT commit -q -m "Event '$(__summary_for_commit "$fpath") ...' has now status $status" -- "$fpath"
|
|
fi
|
|
}
|
|
|
|
# Toggle status flag: CONFIRMED <-> TENTATIVE
|
|
#
|
|
# @input $1: path to iCalendar file
|
|
__tentative_toggle() {
|
|
fpath="$ROOT/$1"
|
|
status=$(awk -v field="STATUS" "$AWK_GET" "$fpath")
|
|
newstatus="TENTATIVE"
|
|
if [ "${status:-}" = "$newstatus" ]; then
|
|
newstatus="CONFIRMED"
|
|
fi
|
|
filetmp=$(mktemp)
|
|
awk -v field="STATUS" -v value="$newstatus" "$AWK_SET" "$fpath" >"$filetmp"
|
|
mv "$filetmp" "$fpath"
|
|
if [ -n "${GIT:-}" ]; then
|
|
$GIT add "$fpath"
|
|
$GIT commit -q -m "Event '$(__summary_for_commit "$fpath") ...' has now status $status" -- "$fpath"
|
|
fi
|
|
}
|
|
|
|
# Prepend attachment to iCalendar file
|
|
#
|
|
# @input $1: path to iCalendar file
|
|
__add_attachment() {
|
|
fpath="$ROOT/$1"
|
|
sel=$(
|
|
$FZF --prompt="Select attachment> " \
|
|
--walker="file,hidden" \
|
|
--walker-root="$HOME" \
|
|
--expect="ctrl-c,ctrl-g,ctrl-q,esc"
|
|
)
|
|
key=$(echo "$sel" | head -1)
|
|
f=$(echo "$sel" | tail -1)
|
|
if [ -n "$key" ]; then
|
|
f=""
|
|
fi
|
|
if [ -z "$f" ] || [ ! -f "$f" ]; then
|
|
return
|
|
fi
|
|
filename=$(basename "$f")
|
|
mime=$(file -b -i "$f" | cut -d ';' -f 1)
|
|
if [ -z "$mime" ]; then
|
|
mime="application/octet-stream"
|
|
fi
|
|
fenc=$(mktemp)
|
|
base64 "$f" >"$fenc"
|
|
filetmp=$(mktemp)
|
|
awk -v file="$fenc" -v mime="$mime" -v filename="$filename" "$AWK_ATTACH" "$fpath" >"$filetmp"
|
|
mv "$filetmp" "$fpath"
|
|
if [ -n "${GIT:-}" ]; then
|
|
$GIT add "$fpath"
|
|
$GIT commit -q -m "Added attachment to '$(__summary_for_commit "$fpath") ...'" -- "$fpath"
|
|
fi
|
|
rm "$fenc"
|
|
}
|