Bir dbus hizmeti altındaki tüm nesne yolları nasıl listelenir?


16

Bu, mevcut DBus hizmetlerinin listesi için bir takip sorusudur .

Aşağıdaki python kodu, kullanılabilir tüm DBus hizmetlerini listeler.

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

Python'daki hizmetlerin altındaki nesne yollarını nasıl listeleriz? Tercih olmasına rağmen cevabın python içermemesi sorun yaratmaz.

Ubuntu 14.04 kullanıyorum


Tercih olmasına rağmen cevabın python içermemesi sorun yaratmaz.
user768421

Yanıtlar:


15

Resmi belgelere göre ( standart arayüzler altında ):

Çeşitli D-Bus uygulamalarında yararlı olabilecek bazı standart arayüzler vardır.

org.freedesktop.DBus.Introspectable

Bu arayüzün bir yöntemi vardır:

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

Nesneleri , arabirimleri (sinyaller ve yöntemler ile), nesne yolu ağacında altındaki nesneler ve özellikleri dahil olmak üzere, nesnenin XML açıklamasını Introspectdöndüren nesneler örnekleri uygulayabilir .

İşte size başlamanız gereken çok basit bir örnek. Kullanır xml.etree.ElementTreeve 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')

org.freedesktop.UPowerÖrn. İle başlayan özyineli olarak içgözlem yapar /org/freedesktop/UPowerve tüm nesne yollarını (düğüm adları) yazdırır:

/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

ki bu kullandığınızda elde edeceğiniz şeydir d-feet(ihtiyacınız olduğu değil):

resim açıklamasını buraya girin


Elbette, komut satırından nesne yollarını kolayca alabilirsiniz gdbus:

gdbus introspect --system --dest org.freedesktop.UPower --object-path \
/ org / freedesktop / UPower - söylem | awk '/ ^ * düğüm / {print $ 2}'
/ Org / freedesktop'un / UPower
/ Org / freedesktop'un / UPower / wakeups
/ Org / freedesktop'un / UPower / cihazlar
/ Org / freedesktop'un / UPower / cihazlar / DisplayDevice
/ Org / freedesktop'un / UPower / cihazlar / battery_BAT0
/ Org / freedesktop'un / UPower / cihazlar / line_power_ADP0

Ben sahip olmayan qdbusyüklü ancak uygun bu sayfayı

qdbus --system org.freedesktop.UPower

benzer bir sonuç vermelidir.


Nesne yollarının bir listesini nasıl oluştururum rec_intro(bus, 'org.freedesktop.UPower', '/org/freedesktop/UPower')?
Khurshid Alam

Hayır, yani, nesne yollarının bir python listesini oluşturmak, böylece listede belirli bir nesne yolu varsa (betiğimde) kontrol edebilirim. Nesne yolunu iyi basar., Ama ben böyle bir şey istiyorum k = rec_intro(bus, 'org.freedesktop.UPower', '/org/freedesktop/UPower'). Fonksiyonu biraz değiştirerek mümkün olduğunu düşünüyorum.
Khurshid Alam

Qbus ile örnek kod:bus = dbus.SessionBus()..... obj_path = '/org/gnome/Gnote/RemoteControl'.......... cmd = 'qdbus org.gnome.Gnote'......... while obj_path not in ((subprocess.check_output(cmd, shell=True)).decode("utf-8")).split("\n"): ........pass
Alam

@KhurshidAlam - fonksiyon örneğin önce bir liste başlatmak mylist=[]sonra yerini printile mylist.appendbu fonksiyon bloğunda son komut olarak daha sonra ve return mylisthemen hemen orada budur komut dosyası altındaki örn eklenti liste üzerinde ya da her türlü yinelerler sonra yapabilirsiniz ... - for x in mylist: print("OBJ_PATH", x)bir OBJ_PATHönek ile yazdırmak için ...
don_crissti

5

Bunu programlı olarak Python'da yapabileceğinizden emin değilim. Ancak bunu nasıl yapacağınızı anlamak büyük bir baş ağrısı olacaktır. Daha önce yapmaya çalıştım ve Dbus'tan nefret ettim. Her neyse, bir şeyi araştırmak istiyorsanız d-feet kullanmanızı öneririm . Aşağıda benim çaldığın bir görüntü var blogda .

resim açıklamasını buraya girin

Program adını, nesne yolunu vb. Öğrendikten sonra, bunlara erişmek için Python'u kullanabilirsiniz.

Misal

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

Gördüğünüz gibi, basit bir şey yapmak eşek için bir acı. Ama bu Dbus ile elde edebileceğiniz en kolay iş akışı!

Bu nedenle, nesne yollarını, arabirimleri vb. Bulmak için bir GUI aracı kullanın. Daha sonra bu şeylere erişmek için yukarıdaki kod snippet'ini şablon olarak kullanın. Ayrıca, her nesnenin hangi yöntemlere, özelliklere vb. Sahip olduğunu görmek için bunu IPython yorumlayıcısı aracılığıyla yapmanızı öneririm (sekmeye basarak).


d-feetorg.gnome.SettingsDaemon.Powerincelemek istediğim eksik . Kendimi yenilmiş hissediyorum :(
WinEunuuchs2Unix


1

Bir otobüs adının (hizmetinin) nesne yollarını almak için deneyimlerimden bildiklerim, nesne yoluyla '/' yani (yukarıdaki örneği kullanarak) içgözlem yapmak mümkündür

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

bu geri dönmelidir:

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

sonra '/ org' yoluyla iç gözlem yapın

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

bu geri dönmelidir:

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

ve bunun gibi:

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

Nesne yolunun '/' kök olduğu ve her düğümün alt klasör olduğu sabit sürücünün klasör yapısından geçmek gibidir. Bu, belirli bir veri yolu adının (hizmetinin) nesne yollarını almanın ve nesne yollarını içeren bir koleksiyon oluşturmanın en iyi yolu gibi görünüyor


1

Gereğince #don_crissti cevaplar, ben hayata, Bu çözüm arayüzü adı ve yöntemi ve sinyaller bilgilere verir

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.