#!/usr/bin/env python3 import json import dbus from random import randint from threading import Timer from gi.repository import GLib from dbus.mainloop.glib import DBusGMainLoop DEFAULT_NOTIF_TIMEOUT = 10 * 1000 notification_history = [] def set_timeout(fn, ms, *args, **kwargs): t = Timer(ms / 1000, fn, args=args, kwargs=kwargs) t.start() return t def dismiss_notification(notification_id: int): for notification in notification_history: if notification["id"] == notification_id: notification["dismissed"] = True print(json.dumps(notification_history), flush=True) def handle_notification(_, message): keys = ["app_name", "replaces_id", "app_icon", "summary", "body", "actions", "hints", "expire_timeout"] args = message.get_args_list() match message.get_member() : case "Notify": notification = dict([(keys[i], args[i]) for i in range(8)]) notification["dismissed"] = False notification["id"] = randint(0, 8192 * 2) notification_history.append(notification) expire_timeout = int(notification["expire_timeout"]) set_timeout(dismiss_notification, expire_timeout if expire_timeout > 0 else DEFAULT_NOTIF_TIMEOUT, notification["id"]) print(json.dumps(notification_history), flush=True) case "CloseNotification": dismiss_notification(int(args[0])) case _: return if __name__ == "__main__": DBusGMainLoop(set_as_default=True) notification_bus = dbus.SessionBus() notification_bus.add_match_string("type='method_call',interface='org.freedesktop.Notifications',eavesdrop=true") notification_bus.add_message_filter(handle_notification) loop = GLib.MainLoop() loop.run()