157 lines
5.6 KiB
Python
Executable File
157 lines
5.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import dbus
|
|
import time
|
|
import queue
|
|
import threading
|
|
from gi.repository import GLib
|
|
import dbus
|
|
from dbus.mainloop.glib import DBusGMainLoop
|
|
|
|
|
|
class Notification:
|
|
"""
|
|
Reprensent a notification
|
|
|
|
:param name str:
|
|
This is the optional name of the application sending the notification.
|
|
This should be the application's formal name, rather than some sort of
|
|
ID. An example would be "FredApp E-Mail Client," rather than
|
|
"fredapp-email-client."
|
|
|
|
:param notification_id int:
|
|
An optional ID of an existing notification that this notification is
|
|
intended to replace.
|
|
|
|
:param notification_icon str:
|
|
The notification icon.(not yet fully understood, use at your own risks)
|
|
|
|
:param title str:
|
|
This is a single line overview of the notification. For instance, "You
|
|
have mail" or "A friend has come online". It should generally not be
|
|
longer than 40 characters, though this is not a requirement, and server
|
|
implementations should word wrap if necessary.
|
|
|
|
:param content str:
|
|
This is a multi-line body of text. Each line is a paragraph, server
|
|
implementations are free to word wrap them as they see fit.
|
|
The body functionality may not be implemented by the notification
|
|
server, conforming clients should check if it is available before usings
|
|
it (see the GetCapabilities message in Protocol). An implementation is
|
|
free to ignore any requested by the client. As an example one possible
|
|
rendering of actions would be as buttons in the notification popup.
|
|
Actions are sent over as a list of pairs. Each even element in the list
|
|
(starting at index 0) represents the identifier for the action. Each
|
|
odd element in the list is the localized string that will be displayed
|
|
to the user. The default action (usually invoked by clicking the
|
|
notification) should have a key named "default". The name can be
|
|
anything, though implementations are free not to display it.
|
|
|
|
:param hints dict:
|
|
Hints are a way to provide extra data to a notification server that the
|
|
server may be able to make use of. See
|
|
https://specifications.freedesktop.org/notification-spec/notification-\
|
|
spec-latest.html#hints for a list of available hints.
|
|
|
|
:param timeout int:
|
|
The timeout time in milliseconds since the display of the notification
|
|
at which the notification should automatically close. If -1,
|
|
the notification's expiration time is dependent on the notification
|
|
server's settings, and may vary for the type of notification.
|
|
If 0, the notification never expires.
|
|
"""
|
|
def __init__(self,
|
|
name: str = "",
|
|
notification_id: int = 0,
|
|
notification_icon: str = "",
|
|
title: str = "",
|
|
content: str = "",
|
|
actions: list = None,
|
|
hints: dict = None,
|
|
timeout: int = -1
|
|
) -> None:
|
|
self.name = name
|
|
self.notification_id = notification_id
|
|
self.notification_icon = notification_icon
|
|
self.title = title
|
|
self.content = content
|
|
self.actions = actions if actions is not None else []
|
|
self.hints = hints if hints is not None else {"urgency": 1}
|
|
self.timeout = timeout
|
|
|
|
def __str__(self) -> str:
|
|
return f"""{80*"_"}
|
|
Notification :
|
|
name = {self.name}
|
|
notification_id = {self.notification_id}sleep
|
|
notification_icon = {self.notification_icon}
|
|
title = {self.title}
|
|
content = {self.content}
|
|
actions = {self.actions}
|
|
hints = {self.hints}
|
|
timeout = {self.timeout}
|
|
{80*"_"}"""
|
|
|
|
def show(self):
|
|
"""
|
|
Display the notification by sending notification event
|
|
to the dbus interface
|
|
"""
|
|
obj = dbus.Interface(dbus.SessionBus()
|
|
.get_object("org.freedesktop.Notifications",
|
|
"/org/freedesktop/Notifications"),
|
|
"org.freedesktop.Notifications")
|
|
obj.Notify(self.name,
|
|
self.notification_id,
|
|
self.notification_icon,
|
|
self.title,
|
|
self.content,
|
|
self.actions,
|
|
self.hints,
|
|
self.timeout)
|
|
|
|
|
|
notification_queue = queue.Queue()
|
|
|
|
def log_notification(bus, message):
|
|
keys = ["app_name", "replaces_id", "app_icon", "summary",
|
|
"body", "actions", "hints", "expire_timeout"]
|
|
args = message.get_args_list()
|
|
if len(args) == 8:
|
|
notif = dict([(keys[i], args[i]) for i in range(8)])
|
|
notif = Notification(args[0],
|
|
args[1],
|
|
args[2],
|
|
args[3],
|
|
args[4],
|
|
list(args[5]),
|
|
dict(args[6]),
|
|
args[7],)
|
|
notification_queue.put(notif)
|
|
|
|
|
|
stop_event = threading.Event()
|
|
|
|
def monitor_notifications():
|
|
loop = DBusGMainLoop(set_as_default=True)
|
|
session_bus = dbus.SessionBus()
|
|
session_bus.add_match_string(
|
|
"type='method_call',interface='org.freedesktop.Notifications'\
|
|
,member='Notify',eavesdrop=true")
|
|
session_bus.add_message_filter(log_notification)
|
|
while not stop_event.is_set():
|
|
GLib.MainLoop().run()
|
|
|
|
thread = threading.Thread(target=monitor_notifications)
|
|
thread.daemon = True
|
|
|
|
|
|
def start_monitoring():
|
|
thread.start()
|
|
|
|
def stop_monitoring():
|
|
stop_event.set()
|
|
|
|
if __name__ == "__main__":
|
|
n = Notification(title="test",content="je suis le test")
|
|
n.show()
|