Lesen von Desktop-Benachrichtigungen über die Befehlszeile. Debian/UbuntuPython

Python-Programme
Anonymous
 Lesen von Desktop-Benachrichtigungen über die Befehlszeile. Debian/Ubuntu

Post by Anonymous »

Läuft Ubuntu 24.04lts.

Ich versuche, ein Skript zu erstellen, das die Desktop-Benachrichtigungen von dbus abhört und den Absender und die Nachricht in der Befehlszeile ausgibt. Das Endziel besteht darin, eine bestimmte Funktion auszuführen, wenn ich eine bestimmte Benachrichtigung erhalte.
Ich habe versucht, dbus-monitor --session zu verwenden, das Dinge ausdruckt, wenn ich eine Benachrichtigung erhalte, aber ich sehe die eigentliche Benachrichtigung nicht. Gemini AI hat mir beim Schreiben von Python-Code geholfen. Dieser Code wird ausgeführt, aber es passiert nichts, wenn ich eine Benachrichtigung erhalte.

Code: Select all

import asyncio

Code: Select all

from dbus_next.aio import MessageBus

Code: Select all

from dbus_next.constants import BusType, MessageType

Code: Select all

from dbus_next import Message, Variant

Code: Select all

import logging

Code: Select all

# Set up basic logging

Code: Select all

# Note: We are only using INFO level for connection status, 

Code: Select all

# message processing is handled via print() for clarity.

Code: Select all

logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')

Code: Select all

# --- DBus Interface Constants ---

Code: Select all

# The D-Bus service name for notifications

Code: Select all

NOTIF_SERVICE = 'org.freedesktop.Notifications'

Code: Select all

# The D-Bus object path for notifications

Code: Select all

NOTIF_PATH = '/org/freedesktop/Notifications'

Code: Select all

# The D-Bus interface for notifications

Code: Select all

NOTIF_INTERFACE = NOTIF_SERVICE

Code: Select all

# ANSI escape codes for bold text

Code: Select all

BOLD_START = '\033[1m'

Code: Select all

BOLD_END = '\033[0m'

Code: Select all

def message_handler(message):

Code: Select all

    """

Code: Select all

   Generic handler for D-Bus messages, focusing only on new notifications

Code: Select all

    (Notify method calls) and printing the sender, summary, and message body.

Code: Select all

    """

Code: Select all

    if message.interface == NOTIF_INTERFACE:

Code: Select all

        

Code: Select all

        # --- Handle New Notification (Method Call) ---

Code: Select all

        if message.message_type == MessageType.METHOD_CALL and message.member == 'Notify':

Code: Select all

            # Notify arguments: (app_name, replaces_id, app_icon, summary, body, actions, hints, expire_timeout)

Code: Select all

            

Code: Select all

            # Ensure we have enough arguments (at least app_name and body)

Code: Select all

            if len(message.body) >= 8:

Code: Select all

                app_name = message.body[0] # App Name (Sender)

Code: Select all

                summary = message.body[3] # Notification Summary (Title)

Code: Select all

                body_text = message.body[4] # Notification Body (Main message)

Code: Select all

                

Code: Select all

                # Combine summary and body for the message

Code: Select all

                # If both exist, use "Summary: Body". If only one exists, use that.

Code: Select all

                if summary and body_text:

Code: Select all

                    message_content = f"{summary}: {body_text}"

Code: Select all

                elif summary:

Code: Select all

                    message_content = summary

Code: Select all

                else:

Code: Select all

                    message_content = body_text

Code: Select all

                output = f"[{app_name}] {message_content}"

Code: Select all

                

Code: Select all

                # Apply bold formatting if the sender is Discord (case-insensitive check)

Code: Select all

                if app_name.lower() == 'discord':

Code: Select all

                    output = f"{BOLD_START}{output}{BOLD_END}"

Code: Select all

                

Code: Select all

                print(output)

Code: Select all

            

Code: Select all

        # Log other relevant messages (like replies to GetCapabilities)

Code: Select all

        else:

Code: Select all

            logging.debug(f"[D-Bus Message] Type: {message.message_type.name}, Member: {message.member}, Body: {message.body}")

Code: Select all

async def notification_listener(bus):

Code: Select all

    """

Code: Select all

   Configures the bus to listen for all messages related to the

Code: Select all

    org.freedesktop.Notifications interface.

Code: Select all

    """

Code: Select all

    # 1.  Add the generic message handler

Code: Select all

    bus.add_message_handler(message_handler)

Code: Select all

    # 2. Use AddMatch to filter messages directed to this interface

Code: Select all

    # This is crucial for catching the 'Notify' method call.

Code: Select all

   # The rule is updated to match on the specific method call ('Notify') rather than

Code: Select all

   # relying solely on the destination service, which is a more robust way to capture

Code: Select all

    # new notification requests.

Code: Select all

    match_rule = f"type='method_call', interface='{NOTIF_INTERFACE}', member='Notify'"

Code: Select all

    

Code: Select all

    await bus.call(

Code: Select all

        Message(

Code: Select all

            destination='org.freedesktop.DBus',

Code: Select all

            path='/org/freedesktop/DBus',

Code: Select all

            interface='org.freedesktop.DBus',

Code: Select all

            member='AddMatch',

Code: Select all

            signature='s',

Code: Select all

            body=[match_rule]

Code: Select all

        )

Code: Select all

    )

Code: Select all

    logging.info("Listening for ALL D-Bus Messages on org.freedesktop.Notifications interface.")

Code: Select all

    logging.info("To test, send a notification, e.g., 'notify-send Hello World'")

Code: Select all

    

Code: Select all

    # Keep the asyncio loop running indefinitely

Code: Select all

    await asyncio.get_running_loop().create_future()

Code: Select all

async def main():

Code: Select all

    """

Code: Select all

    The main entry point for the script.

Code: Select all

    """

Code: Select all

    try:

Code: Select all

        logging.info(f"Attempting to connect to the D-Bus session bus...")

Code: Select all

        bus = await MessageBus(bus_type=BusType.SESSION).connect()

Code: Select all

        logging.info("Successfully connected to the D-Bus session bus.")

Code: Select all

        

Code: Select all

        # Attempt to call the GetCapabilities method to ensure the service is running

Code: Select all

        reply = await bus.call(

Code: Select all

            Message(

Code: Select all

                destination=NOTIF_SERVICE,

Code: Select all

                path=NOTIF_PATH,

Code: Select all

                interface=NOTIF_INTERFACE,

Code: Select all

                member='GetCapabilities',

Code: Select all

                signature='',

Code: Select all

                body=[]

Code: Select all

            )

Code: Select all

        )

Code: Select all

        

Code: Select all

        if reply.message_type == MessageType.METHOD_RETURN:

Code: Select all

            caps = reply.body[0]

Code: Select all

            logging.info(f"Notification service capabilities retrieved: {caps}")

Code: Select all

            await notification_listener(bus)

Code: Select all

        else:

Code: Select all

            # This often means no notification daemon (like dunst or a desktop environment's service) is running.

Code: Select all

            logging.error("Could not retrieve notification service capabilities. Is a notification daemon running?")

Code: Select all

    except Exception as e:

Code: Select all

        logging.error(f"Error during D-Bus setup or initial capability check:   {e}")

Code: Select all

if __name__ == "__main__":

Code: Select all

    try:

Code: Select all

        # Run the main coroutine

Code: Select all

        asyncio.run(main())

Code: Select all

    except KeyboardInterrupt:

Code: Select all

        logging.info("Notification listener stopped by user.")

Code: Select all

    except Exception as e:

Code: Select all

        logging.error(f"An unexpected error occurred: {e}")
Es scheint, dass dies eine einfache Aufgabe sein sollte. Ich würde lieber ein Bash-Skript verwenden, wenn ich könnte, aber Python wäre auch in Ordnung.
Ich habe [diesen Beitrag][1] gefunden, der ein Python-Skript hatte, das ich aktualisieren musste, um mit py3 zu funktionieren. Dieses Skript wird ausgeführt, aber es passiert nichts, wenn ich eine Benachrichtigung erhalte oder eine über „notify-send“ sende

Code: Select all

import gi

Code: Select all

gi.require_version("Gtk", "3.0") # or "4.0" depending on your target GTK version

Code: Select all

from gi.repository import Gtk

Code: Select all

import dbus

Code: Select all

from dbus.mainloop.glib import DBusGMainLoop

Code: Select all

def filter_cb(bus, message):

Code: Select all

    # the NameAcquired message comes through before match string gets applied

Code: Select all

    if message.get_member() != "Notify":

Code: Select all

        return

Code: Select all

    args = message.get_args_list()

Code: Select all

    # args are

Code: Select all

    # (app_name, notification_id, icon, summary, body, actions, hints, timeout)

Code: Select all

    print("Notification from app '%s'" % args[0])

Code: Select all

    print("Summary: %s" % args[3])

Code: Select all

    print("Body: %s", args[4])

Code: Select all

DBusGMainLoop(set_as_default=True)

Code: Select all

bus = dbus.SessionBus()

Code: Select all

bus.add_match_string(

Code: Select all

    "type='method_call',interface='org.freedesktop.Notifications',member='Notify'")

Code: Select all

bus.add_message_filter(filter_cb)

Code: Select all

Gtk.main()
Vielen Dank.
[1]: http://askubuntu.com/questions/38733/ho ... tor-output

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post