~mil/sxmo-devel

sxmo-utils: sxmo_notification*.sh: Rework and cleanup v1 SUPERSEDED

Willow Barraco: 1
 sxmo_notification*.sh: Rework and cleanup

 9 files changed, 196 insertions(+), 185 deletions(-)
#1178130 test.yml success
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~mil/sxmo-devel/patches/50440/mbox | git am -3
Learn more about email & git

[PATCH sxmo-utils] sxmo_notification*.sh: Rework and cleanup Export this patch

This is a complete rewrite, and group every scripts in a single
sxmo_notifs.sh one.

Also: Replace the watch file feature with a more generic notification group
one.

This feature make the user to miss notifications if the conversation file is
already open. It also cause problems when used with Syncthing, as this cause
notifications to be dropped when it synchronise files. It is also pointless
now that opening a notification to an opened conversation just focus the
corresponding terminal.

I think that dropping this feature completly is okay, make things simple,
and simplify the code

But in the same time:

Opening a notification should close all other ones for the same
conversations. So to cover this case, we add an optional group when
creating notifications. Discarding a notification now close all related
ones from the same group.

Signed-off-by: Willow Barraco <contact@willowbarraco.fr>
---
 .../services/sxmo_notificationmonitor.service |   2 +-
 scripts/core/sxmo_appmenu.sh                  |   2 +-
 scripts/core/sxmo_notifs.sh                   | 186 ++++++++++++++++++
 scripts/modem/sxmo_mms.sh                     |   5 +-
 scripts/modem/sxmo_modem.sh                   |  10 +-
 scripts/modem/sxmo_vvm.sh                     |   5 +-
 .../notifications/sxmo_notificationmonitor.sh |  80 --------
 .../notifications/sxmo_notificationsmenu.sh   |  58 ------
 .../notifications/sxmo_notificationwrite.sh   |  33 ----
 9 files changed, 196 insertions(+), 185 deletions(-)
 create mode 100755 scripts/core/sxmo_notifs.sh
 delete mode 100755 scripts/notifications/sxmo_notificationmonitor.sh
 delete mode 100755 scripts/notifications/sxmo_notificationsmenu.sh
 delete mode 100755 scripts/notifications/sxmo_notificationwrite.sh

diff --git a/configs/services/sxmo_notificationmonitor.service b/configs/services/sxmo_notificationmonitor.service
index 4d6033a9..c1beb763 100644
--- a/configs/services/sxmo_notificationmonitor.service
+++ b/configs/services/sxmo_notificationmonitor.service
@@ -4,4 +4,4 @@ Description=display notifications popup messages
[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/sxmo_notificationmonitor.sh
ExecStart=/usr/bin/sxmo_notifs.sh monitor
diff --git a/scripts/core/sxmo_appmenu.sh b/scripts/core/sxmo_appmenu.sh
index 539abb39..0cf2ad82 100755
--- a/scripts/core/sxmo_appmenu.sh
+++ b/scripts/core/sxmo_appmenu.sh
@@ -81,7 +81,7 @@ getprogchoices() {
		NNOTIFICATIONS="$(find "$SXMO_NOTIFDIR" -type f | wc -l)"
		if [ "$NNOTIFICATIONS" -gt 0 ]; then
			CHOICES="
				$icon_bel Notifications ($NNOTIFICATIONS) ^ 0 ^ sxmo_notificationsmenu.sh
				$icon_bel Notifications ($NNOTIFICATIONS) ^ 0 ^ sxmo_notifs.sh menu
				$CHOICES
			"
		fi
diff --git a/scripts/core/sxmo_notifs.sh b/scripts/core/sxmo_notifs.sh
new file mode 100755
index 00000000..62b634c7
--- /dev/null
+++ b/scripts/core/sxmo_notifs.sh
@@ -0,0 +1,186 @@
#!/bin/sh
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors

# include common definitions
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh
# shellcheck source=configs/default_hooks/sxmo_hook_icons.sh
. sxmo_hook_icons.sh

_clear_notif_group() {
	find "$SXMO_NOTIFDIR" -type f | while read -r file; do
		if awk NR==1 "$file" | grep -lxq "$1"; then
			rm "$file"
		fi
	done
}

_handle_new_notif_file(){
	file="$1"

	if [ "$(wc -l "$file" | cut -d' ' -f1)" -lt 3 ]; then
		sxmo_log "Invalid notification file $file found, deleting!"
		rm -f "$file"
		return
	fi

	sxmo_hook_notification.sh "$file" &

	group="$(awk NR==1 "$file")"
	action="$(awk NR==2 "$file")"
	msg="$(tail -n+3 "$file" | cut -c1-70)"

	if dunstify --action="2,open" "$msg" | grep -q 2; then
		_clear_notif_group "$group"
		setsid -f sh -c "$action" > /dev/null 2>&1
	fi &
}

_notifications_hook() {
	sxmo_hook_notifications.sh "$(find "$SXMO_NOTIFDIR"/ -type f | wc -l)"
}

monitor() {
	mkdir -p "$SXMO_NOTIFDIR"

	find "$SXMO_NOTIFDIR" -type f | while read -r file; do
		_handle_new_notif_file "$file"
	done

	_notifications_hook

	fifo="$(mktemp -u)"
	mkfifo "$fifo"
	inotifywait -mq -e attrib,move,delete "$SXMO_NOTIFDIR"  >> "$fifo" &
	inotif_pid=$!

	finish() {
		kill "$inotif_pid"
		rm "$fifo"
		exit
	}
	trap 'finish' TERM INT EXIT

	while read -r notif_folder notif_type notif_file; do
		if echo "$notif_type" | grep -qE "CREATE|MOVED_TO|ATTRIB"; then
			_handle_new_notif_file "$notif_folder$notif_file"
		fi
		_notifications_hook
	done < "$fifo"

	wait "$inotif_pid"
}

_menu_lines() {
	find "$SXMO_NOTIFDIR" -type f | while read -r file; do
		msg="$(tail -n+3 "$file" | tr "\n^" " ")"
		hrandmin="$(stat --printf %y "$file" | grep -oE '[0-9]{2}:[0-9]{2}')"
		cat <<EOF
$hrandmin $msg^$file
EOF
	done
}

menu() {
	choices="$(cat <<EOF
$icon_cls Close Menu
$icon_del Clear Notifications
$(_menu_lines)
EOF
	)"

	picked="$(
		printf "%b" "$choices" |
		cut -d^ -f1 |
		sxmo_dmenu.sh -i -p "Notifs"
	)"

	case "$picked" in
		"$icon_cls Close Menu"|"")
			exit
			;;
		"$icon_del Clear Notifications")
			rm "$SXMO_NOTIFDIR"/*
			# we must update statusbar here because this function depends
			# on number of files in $SXMO_NOTIFDIR
			sxmo_hook_statusbar.sh notifications
			exit
			;;
		*)
			file="$(
				printf "%b" "$choices" |
				grep -F "$picked" |
				cut -d^ -f2
			)"
			group="$(awk NR==1 "$file")"
			action="$(awk NR==2 "$file")"
			_clear_notif_group "$group"
			setsid -f sh -c "$action" > /dev/null 2>&1
			;;
	esac
}

new() {
	while : ; do
		case "$1" in
			-i)
				id="$2"
				shift 2
				;;
			-g)
				group="$2"
				shift 2
				;;
			*)
				break
				;;
		esac
	done

	if [ "$#" -lt 2 ]; then
		usage
		exit 1
	fi

	if [ -z "$id" ]; then
		id="$(tr -dc 'a-zA-Z0-9' < /dev/urandom 2>/dev/null | head -c 10)"
	fi
	if [ -z "$group" ]; then
		group="$(tr -dc 'a-zA-Z0-9' < /dev/urandom 2>/dev/null | head -c 10)"
	fi

	action="$1"
	msg="$2"

	touch "$SXMO_NOTIFDIR/$id"
	printf "%s\n%s\n%b\n" "$group" "$action" "$msg" > "$SXMO_NOTIFDIR/$id"

	sxmo_hook_statusbar.sh notifications
}

usage() {
	cat <<EOF
$(basename "$0"): manage sxmo notifications

Subcommands:
	monitor
		Watch for new notification, dispatch libnotify events, handle actions
	menu
		Open a menu to dismiss notifications
	new [-i id] [-g group] <action> <message...>
		Register a new notification
EOF
}

cmd="$1"
shift
case "$cmd" in
	monitor) monitor "$@";;
	menu) menu "$@";;
	new) new "$@";;
	*)
		usage
		exit 1
		;;
esac
diff --git a/scripts/modem/sxmo_mms.sh b/scripts/modem/sxmo_mms.sh
index a28ed0be..3a198fe0 100755
--- a/scripts/modem/sxmo_mms.sh
+++ b/scripts/modem/sxmo_mms.sh
@@ -191,10 +191,9 @@ processmms() {
			[ -n "$OPEN_ATTACHMENTS_CMD" ] && TEXT="$icon_att $TEXT"
			[ "$NUM_RECIPIENTS" -gt 1 ] && TEXT="$icon_grp $TEXT"

			sxmo_notificationwrite.sh \
				random \
			sxmo_notifs.sh new \
				-g "incoming-message-$LOGDIRNUM" \
				"${OPEN_ATTACHMENTS_CMD}sxmo_hook_tailtextlog.sh \"$LOGDIRNUM\"" \
				"$SXMO_LOGDIR/$LOGDIRNUM/sms.txt" \
				"$SENDER_NAME: $TEXT"
		fi

diff --git a/scripts/modem/sxmo_modem.sh b/scripts/modem/sxmo_modem.sh
index a119bd7f..0daed0ee 100755
--- a/scripts/modem/sxmo_modem.sh
+++ b/scripts/modem/sxmo_modem.sh
@@ -85,10 +85,9 @@ checkforfinishedcalls() {
			stderr "Invoking missed call hook (async)"
			sxmo_hook_missed_call.sh "$CONTACT" &

			sxmo_notificationwrite.sh \
				random \
			sxmo_notifs.sh new \
				-g "incoming-call-$FINISHEDNUMBER" \
				"TERMNAME='$NOTIFMSG' sxmo_terminal.sh sh -c \"echo '$NOTIFMSG at $(date)' && read\"" \
				none \
				"Missed $icon_phn $CONTACT ($FINISHEDNUMBER)"
		fi

@@ -259,10 +258,9 @@ checkfornewtexts() {
		CONTACTNAME=$(sxmo_contacts.sh --name-or-number "$NUM")

		if [ -z "$SXMO_DISABLE_SMS_NOTIFS" ]; then
			sxmo_notificationwrite.sh \
				random \
			sxmo_notifs.sh new \
				-g "incoming-message-$NUM" \
				"sxmo_hook_tailtextlog.sh '$NUM'" \
				"$SXMO_LOGDIR/$NUM/sms.txt" \
				"$CONTACTNAME: $TEXT"

		fi
diff --git a/scripts/modem/sxmo_vvm.sh b/scripts/modem/sxmo_vvm.sh
index 3e418b83..3f345074 100755
--- a/scripts/modem/sxmo_vvm.sh
+++ b/scripts/modem/sxmo_vvm.sh
@@ -36,10 +36,9 @@ processvvm() {
		"$icon_phn $(basename "$VVM_FILE")" >> "$SXMO_LOGDIR/$VVM_SENDER/sms.txt"

	if [ -z "$SXMO_DISABLE_SMS_NOTIFS" ]; then
		sxmo_notificationwrite.sh \
			random \
		sxmo_notifs.sh new \
			-g "incoming-vvm-$VVM_SENDER" \
			"sxmo_open.sh '$VVM_FILE'" \
			"$SXMO_LOGDIR/$VVM_SENDER/sms.txt" \
			"VM: $VVM_SENDER_NAME ($VVM_ID)"
	fi

diff --git a/scripts/notifications/sxmo_notificationmonitor.sh b/scripts/notifications/sxmo_notificationmonitor.sh
deleted file mode 100755
index 76c73768..00000000
--- a/scripts/notifications/sxmo_notificationmonitor.sh
@@ -1,80 +0,0 @@
#!/bin/sh
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors

# include common definitions
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh

handlenewnotiffile(){
	NOTIFFILE="$1"

	if [ "$(wc -l "$NOTIFFILE" | cut -d' ' -f1)" -lt 3 ]; then
		sxmo_log "Invalid notification file $NOTIFFILE found (<3 lines -- see notif spec in sxmo_notifwrite.sh), deleting!"
		rm -f "$NOTIFFILE"
	else
		sxmo_hook_notification.sh "$NOTIFFILE" &
		NOTIFACTION="$(awk NR==1 "$NOTIFFILE")"
		NOTIFWATCHFILE="$(awk NR==2 "$NOTIFFILE")"
		NOTIFMSG="$(tail -n+3 "$NOTIFFILE" | cut -c1-70)"

		(
			dunstify --action="2,open" "$NOTIFMSG" | grep 2 && (
				rm -f "$NOTIFFILE"
				eval "$NOTIFACTION"
			)
		) &

		if lsof | grep -q "$NOTIFWATCHFILE"; then # Already viewing watchfile
			rm -f "$NOTIFFILE"
			return
		fi

		[ -e "$NOTIFWATCHFILE" ] && (
			inotifywait -q "$NOTIFWATCHFILE" && \
				rm -f "$NOTIFFILE" && \
				notifications_hook
		) &
	fi
}

recreateexistingnotifs() {
	for NOTIF in "$SXMO_NOTIFDIR"/*; do
		[ -f "$NOTIF" ] || continue
		handlenewnotiffile "$NOTIF"
	done
}

notifications_hook() {
	sxmo_hook_notifications.sh "$(find "$SXMO_NOTIFDIR"/ -type f | wc -l)"
}

monitorforaddordelnotifs() {
	mkdir -p "$SXMO_NOTIFDIR"

	FIFO="$(mktemp -u)"
	mkfifo "$FIFO"
	inotifywait -mq -e attrib,move,delete "$SXMO_NOTIFDIR"  >> "$FIFO" &
	NOTIFYPID=$!

	finish() {
		kill "$NOTIFYPID"
		rm "$FIFO"
		exit
	}
	trap 'finish' TERM INT EXIT

	while read -r NOTIFFOLDER INOTIFYEVENTTYPE NOTIFFILE; do
		if echo "$INOTIFYEVENTTYPE" | grep -E "CREATE|MOVED_TO|ATTRIB"; then
			handlenewnotiffile "$NOTIFFOLDER/$NOTIFFILE"
		fi
		notifications_hook
	done < "$FIFO"

	wait "$NOTIFYPID"
}

rm -f "$SXMO_NOTIFDIR"/incomingcall
recreateexistingnotifs
notifications_hook
monitorforaddordelnotifs
diff --git a/scripts/notifications/sxmo_notificationsmenu.sh b/scripts/notifications/sxmo_notificationsmenu.sh
deleted file mode 100755
index 7ac9952f..00000000
--- a/scripts/notifications/sxmo_notificationsmenu.sh
@@ -1,58 +0,0 @@
#!/bin/sh
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors

# include common definitions
# shellcheck source=configs/default_hooks/sxmo_hook_icons.sh
. sxmo_hook_icons.sh
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh

notificationmenu() {
	CHOICES="$icon_cls Close Menu\n$icon_del Clear Notifications"
	# shellcheck disable=SC2045
	for NOTIFFILE in $(ls -tr "$SXMO_NOTIFDIR"); do
		NOTIFMSG="$(tail -n+3 "$SXMO_NOTIFDIR/$NOTIFFILE" | tr "\n^" " ")"
		NOTIFHRANDMIN="$(stat --printf %y "$SXMO_NOTIFDIR/$NOTIFFILE" | grep -oE '[0-9]{2}:[0-9]{2}')"
		CHOICES="
			$CHOICES
			$NOTIFHRANDMIN $NOTIFMSG ^ $SXMO_NOTIFDIR/$NOTIFFILE
		"
	done

	PICKEDCONTENT="$(
		printf "%b" "$CHOICES" |
		xargs -0 echo |
		sed '/^[[:space:]]*$/d' |
		awk '{$1=$1};1' |
		cut -d^ -f1 |
		dmenu -i -p "Notifs"
	)"

	[ -z "$PICKEDCONTENT" ] && exit 1
	echo "$PICKEDCONTENT" | grep -q "Close Menu" && exit 1
	if echo "$PICKEDCONTENT" | grep -q "Clear Notifications"; then
		# merely removing the notifs won't remove
		# the inotifywait notifwatchfile. so to handle that
		# we need to open each notifwatchfile
		find "$SXMO_NOTIFDIR" -type f | \
			while read -r line; do
				NOTIFWATCHFILE="$(awk NR==2 "$line")"
				if [ -e "$NOTIFWATCHFILE" ]; then
					cat "$NOTIFWATCHFILE" >/dev/null
				fi
			done
		rm "$SXMO_NOTIFDIR"/*
		# we must update statusbar here because this function depends
		# on number of files in $SXMO_NOTIFDIR
		sxmo_hook_statusbar.sh notifications
		exit 1
	fi

	PICKEDNOTIFFILE="$(echo "$CHOICES" | tr -s ' ' | grep -F "$PICKEDCONTENT" | head -1 | cut -d^ -f2 | tr -d ' ')"
	NOTIFACTION="$(head -n1 "$PICKEDNOTIFFILE")"
	rm -f "$PICKEDNOTIFFILE"
	eval "$NOTIFACTION"
}

notificationmenu
diff --git a/scripts/notifications/sxmo_notificationwrite.sh b/scripts/notifications/sxmo_notificationwrite.sh
deleted file mode 100755
index 2f21257c..00000000
--- a/scripts/notifications/sxmo_notificationwrite.sh
@@ -1,33 +0,0 @@
#!/bin/sh
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors

# include common definitions
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh

# Takes 4 args:
# (1) the filepath of the notification to write (or random to generate a random id)
# (2) action notification invokes upon selecting
# (3) the file to watch for deactivation.
# (4) description of notification
NOTIFFILEPATHTOWRITE="$1"
ACTION="$2"
WATCHFILE="$3"
NOTIFMSG="$4"

writenotification() {
	mkdir -p "$SXMO_NOTIFDIR"
	if [ "$NOTIFFILEPATHTOWRITE" = "random" ]; then
		NOTIFRANDOM="$(tr -dc 'a-zA-Z0-9' < /dev/urandom 2>/dev/null | head -c 10)"
		NOTIFFILEPATHTOWRITE="$SXMO_NOTIFDIR/$NOTIFRANDOM"
	fi
	touch "$NOTIFFILEPATHTOWRITE"
	printf "%s\n%s\n%b\n" \
		"$ACTION" "$WATCHFILE" "$NOTIFMSG" \
		> "$NOTIFFILEPATHTOWRITE"
}

[ "$#" -lt 4 ] && echo "Need >=4 args to create a notification" && exit 1
writenotification
sxmo_hook_statusbar.sh notifications
-- 
2.44.0
sxmo-utils/patches/test.yml: SUCCESS in 22s

[sxmo_notification*.sh: Rework and cleanup][0] from [Willow Barraco][1]

[0]: https://lists.sr.ht/~mil/sxmo-devel/patches/50440
[1]: mailto:contact@willowbarraco.fr

✓ #1178130 SUCCESS sxmo-utils/patches/test.yml https://builds.sr.ht/~mil/job/1178130
I sent a rebased version of this one. Marked as superseded.