web-dev-qa-db-fra.com

Comment répertorier tous les chemins d'objets sous un service de DBU?

Ceci est une question de suivi à ne liste de services DBUS disponibles .

Le suivant python code va répertorier tous les services DBUS disponibles.

import dbus
for service in dbus.SystemBus().list_names():
    print(service)

Comment répertorions-nous les chemins d'objets sous les services de Python? C'est bon si la réponse n'implique pas python bien que cela soit préféré.

J'utilise Ubuntu 14.04

17
user768421

QT Les configurations offrent le moyen le plus pratique de le faire, via qdbus:

qdbus --system org.freedesktop.UPower

imprimerie

/
/org
/org/freedesktop
/org/freedesktop/UPower
/org/freedesktop/UPower/Wakeups
/org/freedesktop/UPower/devices
/org/freedesktop/UPower/devices/line_power_ADP0
/org/freedesktop/UPower/devices/DisplayDevice
/org/freedesktop/UPower/devices/battery_BAT0

Quant au python Way ... par le fonctionnaire - Docs (sous interfaces standard):

Certaines interfaces standard peuvent être utiles à travers diverses applications D-bus.

org.freedesktop.dbus.Introspectable

Cette interface a une méthode:

org.freedesktop.DBus.Introspectable.Introspect (out STRING xml_data)

Les instances d'objets peuvent implémenter Introspect qui renvoie un [~ # ~] xml [~ # ~] Description de l'objet, y compris ses interfaces (avec des signaux et des méthodes), des objets ci-dessous Dans l'arbre de cheminement, et ses propriétés.

Voici donc un exemple très simpliste qui devrait vous aider à démarrer. Il utilise xml.etree.ElementTree et dbus :

#!/usr/bin/env python

import dbus
from xml.etree import ElementTree

def rec_intro(bus, service, object_path):
    print(object_path)
    obj = bus.get_object(service, object_path)
    iface = dbus.Interface(obj, 'org.freedesktop.DBus.Introspectable')
    xml_string = iface.Introspect()
    for child in ElementTree.fromstring(xml_string):
        if child.tag == 'node':
            if object_path == '/':
                object_path = ''
            new_path = '/'.join((object_path, child.attrib['name']))
            rec_intro(bus, service, new_path)

bus = dbus.SystemBus()
rec_intro(bus, 'org.freedesktop.UPower', '/org/freedesktop/UPower')

Il intrusion récursive org.freedesktop.UPower À partir de par exemple. /org/freedesktop/UPower et imprime tous les chemins d'objet (noms de noeuds):

/org/freedesktop/UPower
/org/freedesktop/UPower/Wakeups
/org/freedesktop/UPower/devices
/org/freedesktop/UPower/devices/DisplayDevice
/org/freedesktop/UPower/devices/battery_BAT0
/org/freedesktop/UPower/devices/line_power_ADP0

qui est à peu près ce que vous obtiendrez si vous avez utilisé d-feet (pas que vous en auriez besoin):

enter image description here

16
don_crissti

Je ne suis pas sûr que vous puissiez le faire par programme à Python. Vous pourriez, mais ce sera un mal à la tête énorme pour comprendre comment. J'ai essayé de le faire avant et avons fini par détester les DBU. Quoi qu'il en soit, je recommande d'utiliser D-Pieds Si vous souhaitez enquêter sur des choses. Ci-dessous une capture d'écran que j'ai volée de mon blog .

enter image description here

Une fois que vous connaissez le nom du programme, le chemin d'objet, etc. Vous pouvez ensuite utiliser Python pour accéder à ces choses.

exemple

progname = 'org.freedesktop.NetworkManager'
objpath  = '/org/freedesktop/NetworkManager'
intfname = 'org.freedesktop.NetworkManager'
methname = 'GetDevices'

bus = dbus.SystemBus()

obj  = bus.get_object(progname, objpath)  # Here we get object
intf = dbus.Interface(obj, intfname)      # Here we get interface
meth = inf.get_dbus_method(methname)      # Here we get method

meth()                                    # And finally calling the method

Comme vous le voyez, c'est une douleur dans le cul pour obtenir une chose simple. Mais c'est le workflow le plus facile que vous puissiez obtenir avec DBU!

Ainsi, utilisez un outil d'interface graphique pour trouver les chemins d'objets, les interfaces, etc., utilisez ensuite le code ci-dessus en tant que modèle pour accéder à ces choses. De plus, je vous suggère de faire cela via l'interprète d'Ipython pour voir quelles méthodes, propriétés, etc. Chaque objet a (en frappant l'onglet).

6
Pithikos

Si le service a un objet implémentant org.freedesktop.DBus.ObjectManager, sa méthode GetManagedObjects retourne "Tous les objets, interfaces et propriétés dans un appel de méthode unique." Par exemple, UDISKS2 a un tel objet.

2
beroal

Ce que je sais de mon expérience pour obtenir les chemins d'objets d'un nom de bus (service), il est possible d'intrigité avec le chemin d'objet '/' I.e. (Utilisation de l'exemple ci-dessus)

introspectfunc('org.freedesktop.UPower', '/') 

cela devrait revenir:

<node name="/"> 
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/></node>

puis introspect avec le chemin '/ org'

introspectfunc('org.freedesktop.UPower', '/org')

cela devrait revenir:

<node name="/org"> 
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/></node>

etc:

introspectfunc('org.freedesktop.UPower', '/org/freedesktop')
introspectfunc('org.freedesktop.UPower', '/org/freedesktop/UPower')
etc.

C'est comme passer à travers la structure de dossiers du disque dur où le chemin d'objet '/' est la racine et chaque nœud est le sous-dossier. Cela semble le meilleur moyen de récupérer les chemins d'objet d'un nom de bus particulier (service) et de construire une collection contenant les chemins d'objets

1
qnbibiqn

Selon - # Don_crissti réponses, j'ai implémenté cette solution, cette solution donne au nom d'interface et à la méthode et aux informations de signaux

import dbus
from xml.etree import ElementTree
bus = dbus.SystemBus()

def busNames():
    return [ name for name in  bus.list_names() if not name.startswith(":") ]


def pathNames(service,object_path="/",paths=None,serviceDict=None):
    if paths == None:
        paths = {}
    paths[object_path] = {}
    obj = bus.get_object(service, object_path)
    iface = dbus.Interface(obj, 'org.freedesktop.DBus.Introspectable')
    xml_string = iface.Introspect()
    root = ElementTree.fromstring(xml_string)
    for child in root:
        if child.tag == 'node':
            if object_path == '/':
                    object_path = ''
            new_path = '/'.join((object_path, child.attrib['name']))
            pathNames(service, new_path,paths)
        else:
            if object_path == "":
                object_path = "/"
            functiondict = {}
            paths[object_path][child.attrib["name"]] = functiondict
            for func in child.getchildren():
                if func.tag not in functiondict.keys():
                    functiondict[func.tag] =[]
                functiondict[func.tag].append(func.attrib["name"])
    if serviceDict == None:
        serviceDict = {}
    serviceDict[service] = paths
    return serviceDict



import json
import random
service=random.sample(busNames(),1).pop()
print service
print json.dumps(pathNames(service),indent=3)
1
Reegan Miranda