new file mode 100644
@@ -0,0 +1,81 @@
+#
+# Copyright (C) 2021 TDT AG <development@tdt.de>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See https://www.gnu.org/licenses/gpl-2.0.txt for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=system-notification
+PKG_VERSION:=0.1
+PKG_RELEASE:=1
+
+PKG_MAINTAINER:=Florian Eckert <fe@dev.tdt.de>
+PKG_LICENSE:=GPL-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/system-notification
+ SECTION:=base
+ CATEGORY:=Base system
+ TITLE:=System notification
+endef
+
+define Package/system-notification/description
+ This package provides a ubus backend that can be used to save system
+ notification. The notifications are not persistent. They are lost after
+ every reboot.
+
+ The following ubus methods are available:
+
+ add:
+ The <add> command adds a notification to the ubus backend.
+ ubus call system.notification add '{"title":"<string>","description":"<description>"}'
+ In addition, the following json string could be optional set.
+ * url: {"url": "<string>"} Additional information are available at this extrenal URL.
+ * opkg: {"package": "<string>"} Package can be updated.
+
+ remove:
+ The <remove> command removes a notification from the ubus backend.
+ ubus call system.notification remove '{"uuid": "<string>"}'
+
+ list:
+ The <list> command dumps all staged notification from the ubus backend.
+ ubus call system.notification list
+
+ flush:
+ The <flush> command removes all stage notification from the ubus backend.
+ ubus call system.notification flush
+endef
+
+define Build/Compile
+endef
+
+define Package/system-notification/postinst
+#!/bin/sh
+if [ -z "$${IPKG_INSTROOT}" ] && [ -x /etc/init.d/rpcd ]; then
+ /etc/init.d/rpcd restart
+fi
+exit 0
+endef
+
+define Package/system-notification/postrm
+#!/bin/sh
+if [ -z "$${IPKG_INSTROOT}" ] && [ -x /etc/init.d/rpcd ]; then
+ /etc/init.d/rpcd restart
+fi
+exit 0
+endef
+
+define Package/system-notification/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) ./files/usr/bin/system-notification \
+ $(1)/usr/bin/system-notification
+
+ $(INSTALL_DIR) $(1)/usr/libexec/rpcd
+ $(INSTALL_BIN) ./files/usr/libexec/rpcd/system.notification \
+ $(1)/usr/libexec/rpcd/
+endef
+
+$(eval $(call BuildPackage,system-notification))
new file mode 100644
@@ -0,0 +1,105 @@
+#!/bin/sh
+# Copyright (C) 2021 TDT AG <development@tdt.de>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See https://www.gnu.org/licenses/gpl-2.0.txt for more information.
+#
+
+. /usr/share/libubox/jshn.sh
+
+remove() {
+ local uuid="$1"
+
+ json_init
+ json_add_string "uuid" "$uuid"
+ ubus call system.notification remove "$(json_dump)"
+ json_cleanup
+}
+
+list() {
+ local title description uuid timestamp
+
+ json_init
+ json_load "$(ubus call system.notification list)"
+ json_select "messages" 1>/dev/null 2>&1
+ [ $? -eq 0 ] || {
+ echo "No notifications are available"
+ return
+ }
+
+ json_get_keys notifications
+ for notification in $notifications; do
+ json_select "$notification"
+ json_get_vars title description uuid timestamp
+
+ echo "$title"
+ echo ""
+ echo "$description"
+
+ json_select "actions" 1>/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ json_get_keys actions
+ for action in $actions; do
+ json_select "$action"
+ local action
+ json_get_var entry action
+ [ "$entry" = "link" ] && {
+ local url
+ json_get_var url url
+ echo "- Check $url for more information"
+ }
+
+ [ "$entry" = "opkg" ] && {
+ local package
+ json_get_var package package
+ echo "- To upgrade, execute \"opkg upgrade $package\""
+ }
+ json_select ..
+ done
+ json_select ..
+ fi
+
+ local dstring
+ echo ""
+ dstring="$(date +"%Y-%m-%d %H:%M:%S" -d "@${timestamp}")"
+ echo "date: $dstring"
+ echo "uuid: $uuid"
+ echo "---"
+ json_select ..
+ done
+ json_select ..
+}
+
+usage() {
+ local msg="$1"
+
+ if [ -n "$msg" ]; then
+ echo "$msg"
+ echo ""
+ fi
+
+ echo "Usage: $(basename "$0") <command>"
+ echo ""
+ echo "commmand:"
+ echo ""
+ echo "remove <uuid>: Remove notification"
+ echo "list : Show notification"
+}
+
+main() {
+ cmd="$1"
+ uuid="$2"
+
+ case "$cmd" in
+ remove)
+ remove "$uuid"
+ ;;
+ list)
+ list
+ ;;
+ *)
+ usage "Command not supported"
+ esac
+}
+
+main "$@"
new file mode 100644
@@ -0,0 +1,220 @@
+#!/bin/sh
+#
+# Copyright (C) 2021 TDT AG <development@tdt.de>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See https://www.gnu.org/licenses/gpl-2.0.txt for more information.
+#
+
+. /usr/share/libubox/jshn.sh
+
+MESSAGE_DIR="/tmp/notification/messages.d"
+MESSAGE_MAX=20
+
+get_uuid() {
+ local file="$1"
+ local uuid
+
+ uuid="${file##*/}"
+
+ echo "${uuid%*.json}"
+}
+
+gen_uuid() {
+ cat /proc/sys/kernel/random/uuid
+}
+
+list() {
+ json_init
+
+ json_add_object "add"
+ json_add_string "title"
+ json_add_string "description"
+ json_add_string "url"
+ json_add_string "package"
+ json_close_object
+
+ json_add_object "remove"
+ json_add_string "uuid"
+ json_close_object
+
+ json_add_object "list"
+ json_close_object
+
+ json_add_object "flush"
+ json_close_object
+
+ json_dump
+}
+
+notification_add() {
+ local title="$1"
+ local description="$2"
+ local url="$3"
+ local package="$4"
+
+ local timestamp uuid
+
+ local code=-1
+ local msg="Unable to add notification"
+
+ timestamp="$(date +%s)"
+
+ uuid="$(gen_uuid)"
+ if [ -z "$uuid" ]; then
+ json_init
+ json_add_int "code" "-2"
+ json_add_string "message" "Unable to get uuid"
+ json_dump
+ return
+ fi
+
+ json_init
+ json_add_string title "$title"
+ json_add_string description "$description"
+ json_add_int timestamp "$timestamp"
+ [ -z "$url" ] || json_add_string "url" "$url"
+ [ -z "$package" ] || json_add_string "package" "$package"
+ json_dump > "${MESSAGE_DIR}/${uuid}.json"
+
+ if [ -f "${MESSAGE_DIR}/${uuid}.json" ]; then
+ code=0
+ msg="Notification added"
+ fi
+
+ local count=0
+ for file in "${MESSAGE_DIR}"/*.json; do
+ count=$((count + 1))
+ if [ "$count" -gt "$MESSAGE_MAX" ]; then
+ rm "${MESSAGE_DIR}/${file}"
+ fi
+ done
+
+ json_init
+ json_add_int "code" "$code"
+ json_add_string "message" "$msg"
+ json_dump
+}
+
+notification_remove() {
+ local uuid="$1"
+
+ local code=-1
+ local msg="Notification not found"
+
+
+ if [ -f "${MESSAGE_DIR}/${uuid}.json" ]; then
+ rm "${MESSAGE_DIR}/${uuid}.json"
+ code=0
+ msg="Notication removed"
+ fi
+
+ json_init
+ json_add_int "code" "$code"
+ json_add_string "message" "$msg"
+ json_dump
+}
+
+notification_list() {
+ local uuid title description timestamp url package
+
+ json_init
+ if [ -n "$(ls -A "$MESSAGE_DIR")" ]; then
+ json_add_array "messages"
+ for entry in "${MESSAGE_DIR}"/*.json; do
+ uuid="$(get_uuid "$entry")"
+
+ json_set_namespace dump old_cb
+ json_load_file "$entry"
+ json_get_vars title description timestamp url package
+ json_cleanup
+ json_set_namespace "$old_cb"
+
+ json_add_object ""
+ json_add_string uuid "$uuid"
+ json_add_string title "$title"
+ json_add_string description "$description"
+ json_add_int timestamp "$timestamp"
+ json_add_array actions
+ json_add_object
+ json_add_string action dismiss
+ json_close_object
+ [ -z "$url" ] || {
+ json_add_object
+ json_add_string action link
+ json_add_string url "$url"
+ json_close_object
+ }
+ [ -z "$package" ] || {
+ json_add_object
+ json_add_string action opkg
+ json_add_string package "$package"
+ json_close_object
+ }
+ json_close_array
+ json_close_object
+ done
+ json_close_array
+ fi
+ json_dump
+}
+
+notification_flush() {
+ local code=0
+ local msg="All notifications flushed"
+
+ rm "$MESSAGE_DIR"/*.json
+
+ json_init
+ json_add_int "code" "$code"
+ json_add_string "message" "$msg"
+ json_dump
+}
+
+call() {
+ local method="$1"
+
+ local title description url package uuid
+
+ case "$method" in
+ add)
+ read -r input;
+ json_load "${input}"
+ json_get_var title title
+ json_get_var description description
+ json_get_var url url
+ json_get_var package package
+ notification_add "$title" "$description" "$url" "$package"
+ ;;
+ remove)
+ read -r input;
+ json_load "${input}"
+ json_get_var uuid uuid
+ notification_remove "$uuid"
+ ;;
+ list)
+ notification_list
+ ;;
+ flush)
+ notification_flush
+ ;;
+ esac
+}
+
+main() {
+ local path="$1"
+ local method="$2"
+
+ mkdir -p "${MESSAGE_DIR}"
+
+ case "$path" in
+ list)
+ list
+ ;;
+ call)
+ call "$method"
+ ;;
+ esac
+}
+
+main "$@"
This package provides a ubus backend that can be used to save system notification. The notifications are not persistent. They are lost after every reboot. The following ubus methods are available: add: The <add> command adds a notification to the ubus backend. ubus call system.notification add '{"title":"<string>","description":"<description>"}' In addition, the following json string could be optional set. * url: {"url": "<string>"} Additional information are available at this extrenal URL. * opkg: {"package": "<string>"} Package can be updated. remove: The <remove> command removes a notification from the ubus backend. ubus call system.notification remove '{"uuid": "<string>"}' list: The <list> command dumps all staged notification from the ubus backend. ubus call system.notification list flush: The <flush> command removes all stage notification from the ubus backend. ubus call system.notification flush Signed-off-by: Florian Eckert <fe@dev.tdt.de> --- package/utils/system-notification/Makefile | 81 +++++++ .../files/usr/bin/system-notification | 105 +++++++++ .../usr/libexec/rpcd/system.notification | 220 ++++++++++++++++++ 3 files changed, 406 insertions(+) create mode 100644 package/utils/system-notification/Makefile create mode 100644 package/utils/system-notification/files/usr/bin/system-notification create mode 100644 package/utils/system-notification/files/usr/libexec/rpcd/system.notification