web-dev-qa-db-ja.com

dbusサービスの下のすべてのオブジェクトパスを一覧表示する方法

これは 利用可能なDBusサービスのリスト へのフォローアップ質問です。

次のpythonコードは、利用可能なすべてのDBusサービスをリストします。

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

Pythonのサービスの下のオブジェクトパスをリストするにはどうすればよいですか?回答にpythonが含まれていなくてもかまいませんが、それが推奨されます。

Ubuntu 14.04を使用しています

17
user768421

QTセットアップは、qdbusを使用して、最も便利な方法を提供します。

qdbus --system org.freedesktop.UPower

プリント

/
/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

python way ...公式について docs (understandard interfaces)について):

さまざまなD-Busアプリケーションで役立つ可能性のある標準インターフェースがいくつかあります。

org.freedesktop.DBus.Introspectable

このインターフェースには1つのメソッドがあります。

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

オブジェクトインスタンスはIntrospectを実装する場合があり、これはオブジェクトの[〜#〜] xml [〜#〜]記述を返します。 、オブジェクトパスツリーでその下にあるオブジェクト、およびそのプロパティ。

だから、これはあなたが始めるための非常に単純な例です。 xml.etree.ElementTreedbus を使用します:

#!/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')

org.freedesktop.UPowerを再帰的にイントロスペクトします。 /org/freedesktop/UPowerおよびすべてのオブジェクトパス(ノード名)を出力します。

/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

これは、d-feetを使用した場合に得られるものとほぼ同じです(必要ない場合)。

enter image description here

16
don_crissti

これをプログラムでPythonで実行できるかどうかはわかりません。かもしれませんが、その方法を理解することは大きな頭痛の種になるでしょう。私は以前にそれをやろうとして、結局Dbusを嫌っていました。とにかく、あなたが物事を調査したいのなら、私は d-feet を使うことを勧めます。以下は blog から盗んだスクリーンショットです。

enter image description here

プログラム名、オブジェクトパスなどがわかったら、Pythonを使用してそれらにアクセスできます。

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

ご覧のとおり、単純なことを行うのはお尻の痛みです。しかし、これはDbusで取得できる最も簡単なワークフローです。

したがって、GUIツールを使用して、オブジェクトのパスやインターフェイスなどを見つけます。次に、上記のコードスニペットをテンプレートとして使用して、これらにアクセスします。また、IPythonのインタープリターを介してこれを実行し、各オブジェクトが持つメソッド、プロパティなどを確認することをお勧めします(タブを押す)。

6
Pithikos

サービスにorg.freedesktop.DBus.ObjectManagerを実装するオブジェクトがある場合、そのメソッドGetManagedObjects「すべてのオブジェクト、インターフェース、およびプロパティを1回のメソッド呼び出しで返します。」 たとえば、UDisks2にはそのようなオブジェクト。

2
beroal

私の経験からバス名(サービス)のオブジェクトパスを取得するために知っていることは、オブジェクトパス '/'でイントロスペクトすること(つまり、上記の例を使用)です。

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

これは返すべきです:

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

次に、パス '/ org'で内省します

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

これは返すべきです:

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

等々:

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

これは、オブジェクトパス「/」がルートで、すべてのノードがサブフォルダーであるハードドライブのフォルダー構造をたどるようなものです。これは、特定のバス名(サービス)のオブジェクトパスを取得し、オブジェクトパスを含むコレクションを構築する最良の方法のようです

1
qnbibiqn

#don_crissti の回答に従って、私は実装しました。このソリューションは、インターフェースの名前とメソッド、およびシグナル情報を提供します

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