Comment lire la sortie du moniteur dbus?

17

Je joue avec moniteur dbus pour essayer de comprendre comment fonctionne dbus Environnement Ubuntu. J'ai plusieurs questions à ce sujet:

  1. Pourriez-vous s'il vous plaît laissez-moi savoir comment lire correctement ce qui suit? Je comprends la grande idée, mais pas les détails.

    signal sender=:1.1948 -> dest=(null destination) serial=1829990 path=/org/ayatana/menu/DA00003; interface=org.ayatana.dbusmenu; member=ItemPropertyUpdated
    int32 23
    string "enabled"
    variant boolean true
    method call sender=:1.6 -> dest=org.freedesktop.Notifications serial=1399 path=/org/freedesktop/Notifications; interface=org.freedesktop.Notifications;
    member=GetCapabilities
    

    Je comprends que le premier est un signal alors que le second est une méthode. Est-ce que destination signifie qu’il peut y avoir un récepteur / emplacement spécifique pour un signal? Qu'est-ce qu'un membre ? Et les éléments de la liste suivant le signal les arguments passés dans le signal? Que sont expéditeur et publications en série ?

  2. J'ai remarqué quelque chose à propos de la relation entre le contrôle du volume et les notifications. D'après ce que je lis sur la sortie moniteur dbus

    method call sender=:1.6 -> dest=org.freedesktop.Notifications serial=1400 path=/org/freedesktop/Notifications; interface=org.freedesktop.Notifications; member=Notify
    string "gnome-settings-daemon"
    uint32 0
    string "notification-audio-volume-medium"
    string " "
    string ""
    array [
    ]
    array [
    dict entry(
    string "value"
    variant int32 38
    )
    dict entry(
    string "x-canonical-private-synchronous"
    variant string "volume"
    )
    ]
    int32 -1
    

    Il semble que la notification soit déclenchée par sa méthode. Je ne comprends pas vraiment pourquoi cela fonctionne de cette façon. À mon avis, il serait plus logique qu'un signal soit émis "notification-audio-volume-medium" alors que la notification écoutera ce signal et réagira en conséquence. Si l'envoi / la réception serait publique plutôt que privée, ne permettrait-il pas plus de flexibilité et d'efficacité? Par exemple, s'il y avait un signal public pour "notification-audio-volume-medium" , plusieurs applications pourraient écouter ce signal (ce qui permettrait aux applications de notification concurrentes de voir le jour) et les développeurs doivent être concernés par l'envoi de signaux, tandis que ramasser et gérer un signal serait l'entreprise de l'application de notification (ou tout autre programme qui a besoin de ces signaux).

  3. Je suis juste nouveau sur Dbus et je veux en savoir plus car je travaille avec Dbus sur Python, principalement pour développer des applets. J'ai vu le tutoriel dbus-python et apprend à écouter tous les signaux (en ne spécifiant ni interface ni chemin, etc.) Mais comment suivre les méthodes quand elles sont appelées, comme le fait dbus-monitor?

Si vous avez la patience d’enseigner comment cela fonctionne, vous êtes les bienvenus.

    
posée Benjamin 01.05.2011 - 10:18
la source

2 réponses

21

Introduction au D-Bus

  • D-Bus permet de communiquer entre services . Les services peuvent être anonymes (identifiés uniquement par l'adresse de bus, par exemple: 1.6), et les services peuvent acquérir des noms bien connus , tels que org.freedesktop.Notifications ou org.freedesktop.NetworkManager . L'expéditeur et la destination que vous pouvez voir dans les journaux sont des services. "Destination nulle" signifie une diffusion: livraison à tous les services.

  • Un service peut exporter un ou plusieurs objets vers le bus. Les objets reçoivent des chemins d'objet , tels que /org/freedesktop/NetworkManager/ActiveConnection/1 ou /org/ayatana/menu/DA00003 . Les chemins d'objet utilisent slash comme séparateur, comme les chemins de système de fichiers.

  • Chaque objet peut prendre en charge une ou plusieurs interfaces . Une interface n'est rien d'autre qu'un ensemble de méthodes et de signaux, connus sous le nom de membres (très similaire à l'interface de la POO). Les méthodes et les signaux ont des signatures fixes. Les membres sont toujours placés dans les noms d’interface bien connus .

  • Une fois publiés, les noms connus ne changent jamais .

  • N'importe quel service peut se connecter aux signaux d'un autre service et appeler ses méthodes de manière asynchrone. Tout service peut émettre des signaux.

Signaux

Maintenant à vos questions spécifiques.

signal sender=:1.1948 -> dest=(null destination) serial=1829990 path=/org/ayatana/menu/DA00003; interface=org.ayatana.dbusmenu; member=ItemPropertyUpdated
int32 23
string "enabled"
variant boolean true

Oui, vous avez raison, c'est un signal. Il est diffusé par le service :1.1948 et l'objet "self" est /org/ayatana/menu/DA00003 . Le nom porte le nom ItemPropertyUpdated défini dans l'interface org.ayatana.dbusmenu (comme org.ayatana.dbusmenu::ItemPropertyUpdated en C ++). La série, je suppose, est une sorte d’identifiant unique de l’événement sur le bus.

Ensuite, nous voyons les arguments de signal. Selon la documentation de l'interface , le premier argument int32 est l'ID d'un élément, la deuxième chaîne est son nom de propriété et la troisième variante correspond à la valeur de la propriété. Ainsi, l'objet /org/ayatana/menu/DA00003 nous avertit que l'élément id # 23 a changé sa propriété enabled en true.

Un autre exemple sur les signaux:

signal sender=:1.1602 -> dest=(null destination) serial=20408 path=/im/pidgin/purple/PurpleObject; interface=im.pidgin.purple.PurpleInterface; member=SendingChatMsg
   int32 47893
   string "test"
   uint32 1
signal sender=:1.1602 -> dest=(null destination) serial=20409 path=/im/pidgin/purple/PurpleObject; interface=im.pidgin.purple.PurpleInterface; member=IrcSendingText
   int32 64170
   string "PRIVMSG #chat :test

J'ai envoyé un message texte "test" en utilisant Pidgin à un canal IRC, et /im/pidgin/purple/PurpleObject a émis deux signaux sous l'interface im.pidgin.purple.PurpleInterface : d'abord un SendingChatMsg général, puis un IrcSendingText plus spécifique.

Méthodes

Maintenant, les méthodes. Les méthodes permettent de demander aux objets D-Bus de faire quelque chose ou d'effectuer des requêtes et de renvoyer des données. Ils sont assez similaires aux méthodes classiques de la POO, sauf que les méthodes D-Bus sont appelées de manière asynchrone.

Appelons par programmation une méthode D-Bus.

import dbus, dbus.proxies

#-- connect to the session bus (as opposed to the system bus)
session = dbus.SessionBus()

#-- create proxy object of D-Bus object
obj_proxy = dbus.proxies.ProxyObject(conn=session,
         bus_name="org.freedesktop.Notifications",     #-- name of the service we are retrieving object from
         object_path="/org/freedesktop/Notifications") #-- the object path

#-- create proxy object of the D-Bus object wrapped into specific interface
intf_proxy = dbus.proxies.Interface(obj_proxy, "org.freedesktop.Notifications")

#-- lastly, create proxy object of the D-Bus method
method_proxy = intf_proxy.get_dbus_method("Notify")

#-- ... and call the method
method_proxy("test from python",
             dbus.UInt32(0),
             "bluetooth",     #-- icon name
             "Notification summary",
             "Here goes notification body",
             [], {},
             5) #-- timeout

Notez les arguments, en particulier le nom de l'icône. Dans votre exemple, "notification-audio-volume-medium" était l'icône du haut-parleur de volume à alimentation moyenne.

Services personnalisés

Il est absolument possible d'exécuter vos propres services D-Bus, d'exporter vos propres objets D-Bus et de définir vos propres interfaces D-Bus avec vos propres méthodes et signaux. Tout cela peut être fait facilement en Python une fois que vous avez compris le concept global et que vous avez lu la documentation du module dbus . :)

    
réponse donnée ulidtko 01.05.2011 - 14:31
la source
10

Je cherchais également une solution pour collecter les notifications du bureau via dbus avec un script python. Cette question était la plus proche de ma recherche sur Google, mais écrire un remplacement pour notify-osd me semblait un peu exagéré:)

En regardant les sources d’applets notifications récentes , j’ai eu quelques astuces pour surveiller les messages dbus et voici l’implémentation de python I est venu avec:

import gtk
import dbus
from dbus.mainloop.glib import DBusGMainLoop

def filter_cb(bus, message):
    # the NameAcquired message comes through before match string gets applied
    if message.get_member() != "Notify":
        return
    args = message.get_args_list()
    # args are
    # (app_name, notification_id, icon, summary, body, actions, hints, timeout)
    print("Notification from app '%s'" % args[0])
    print("Summary: %s" % args[3])
    print("Body: %s", args[4])


DBusGMainLoop(set_as_default=True)
bus = dbus.SessionBus()
bus.add_match_string(
    "type='method_call',interface='org.freedesktop.Notifications',member='Notify'")
bus.add_message_filter(filter_cb)
gtk.main()

J'espère que cela aidera quelqu'un, car il semble qu'il n'y ait pas beaucoup d'exemples de python simples liés à la surveillance des messages dbus.

    
réponse donnée Keto 27.05.2012 - 14:23
la source

Lire d'autres questions sur les étiquettes