Dbus सेवा के अंतर्गत सभी ऑब्जेक्ट पथ को कैसे सूचीबद्ध करें?


16

यह उपलब्ध DBus सेवाओं की A सूची का अनुवर्ती प्रश्न है ।

निम्नलिखित अजगर कोड सभी उपलब्ध DBus सेवाओं को सूचीबद्ध करेगा।

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

हम अजगर में सेवाओं के तहत ऑब्जेक्ट पथ को कैसे सूचीबद्ध करते हैं? अगर यह पसंद किया जाता है तो जवाब में अजगर शामिल नहीं है यह ठीक है।

मैं Ubuntu 14.04 का उपयोग कर रहा हूं


अगर यह पसंद किया जाता है तो जवाब में अजगर शामिल नहीं है यह ठीक है।
user768421

जवाबों:


15

आधिकारिक डॉक्स ( मानक इंटरफेस के तहत ) के अनुसार:

कुछ मानक इंटरफेस हैं जो विभिन्न डी-बस अनुप्रयोगों में उपयोगी हो सकते हैं।

org.freedesktop.DBus.Introspectable

इस इंटरफ़ेस में एक विधि है:

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

ऑब्जेक्ट इंस्टेंसेस कार्यान्वित कर सकते हैं Introspectजो ऑब्जेक्ट के XML विवरण को लौटाता है , जिसमें इसके इंटरफेस (सिग्नल और विधियों के साथ), ऑब्जेक्ट पथ ट्री में इसके नीचे की वस्तुएं और इसके गुण शामिल हैं।

तो यहाँ एक बहुत ही सरल उदाहरण है जो आपको शुरू करना चाहिए। यह उपयोग करता है xml.etree.ElementTreeऔर 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से शुरू होता है उदाहरण के लिए /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(ऐसा नहीं है कि आपको इसकी आवश्यकता होगी):

यहाँ छवि विवरण दर्ज करें


ज़रूर, आप आसानी से कमांड लाइन के माध्यम से वस्तु पथ प्राप्त कर सकते हैं जैसे gdbus:

gdbus introspect - सिस्टम --dest org.freedesktop.UPower --object-path \
/ org / freedesktop / UPower --recurse | awk '/ ^ * नोड / {प्रिंट $ 2}'
/ Org / freedesktop / UPOWER
/ Org / freedesktop / UPOWER / Wakeups
/ Org / freedesktop / UPOWER / उपकरणों
/ Org / freedesktop / UPOWER / उपकरणों / DisplayDevice
/ Org / freedesktop / UPOWER / उपकरणों / battery_BAT0
/ Org / freedesktop / UPOWER / उपकरणों / line_power_ADP0

मैंने qdbusस्थापित नहीं किया है, लेकिन इस पृष्ठ के अनुसार

qdbus --system org.freedesktop.UPower

एक समान परिणाम का उत्पादन करना चाहिए।


मैं ऑब्जेक्ट पथों की सूची कैसे बनाऊँ rec_intro(bus, 'org.freedesktop.UPower', '/org/freedesktop/UPower')?
खुर्शीद आलम

नहीं, मेरा मतलब है कि ऑब्जेक्ट पथों की एक अजगर सूची बनाना, ताकि मैं (मेरी स्क्रिप्ट में) जांच कर सकूं कि क्या विशेष ऑब्जेक्ट-पथ सूची में मौजूद है। यह ऑब्जेक्टपथ को ठीक करता है। लेकिन मुझे ऐसा कुछ चाहिए k = rec_intro(bus, 'org.freedesktop.UPower', '/org/freedesktop/UPower')। मुझे लगता है कि फ़ंक्शन को थोड़ा संशोधित करके यह संभव है।
खुर्शीद आलम

कोडबस के साथ उदाहरण कोड: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
खुर्शीद आलम

@KhurshidAlam - एक सूची को प्रारंभ करने से पहले समारोह जैसे mylist=[]तब की जगह printके साथ mylist.appendकि समारोह ब्लॉक में पिछले आदेश के रूप में और उसके बाद return mylist- यह है कि काफी नहीं है क्या ... आप तो पुनरावृति सूची पर या जो भी स्क्रिप्ट के तल पर जैसे जोड़ सकते हैं for x in mylist: print("OBJ_PATH", x)उन्हें एक OBJ_PATHउपसर्ग के साथ मुद्रित करने के लिए ...
डॉन 'क्राइस्टी

5

मुझे यकीन नहीं है कि आप पायथन में यह प्रोग्राम कर सकते हैं। आप यह जान सकते हैं कि यह कैसे पता चलेगा। मैंने पहले इसे करने की कोशिश की और डब से नफरत करने लगा। यदि आप चीजों की जांच करना चाहते हैं तो मैं किसी भी तरह से डी-फीट का उपयोग करने की सलाह देता हूं । नीचे एक स्क्रीनशॉट है जो मैंने अपने ब्लॉग से चुराया है ।

यहाँ छवि विवरण दर्ज करें

एक बार जब आप प्रोग्राम का नाम, ऑब्जेक्ट पथ आदि जानते हैं, तो आप उन चीजों को एक्सेस करने के लिए पायथन का उपयोग कर सकते हैं।

उदाहरण

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 के दुभाषिए के माध्यम से यह देखने के लिए कि प्रत्येक वस्तु में क्या तरीके, गुण आदि हैं (टैब मारकर)।


d-feetगायब है org.gnome.SettingsDaemon.Powerजो मैं निरीक्षण करना चाहता था। मैं पराजित महसूस कर रहा हूँ :(
WinEunuuchs2Unix


1

एक बस नाम (सेवा) के ऑब्जेक्ट पथ को प्राप्त करने के लिए मैं अपने अनुभव से जो जानता हूं, वह ऑब्जेक्ट पथ '/' के साथ आत्मनिरीक्षण करना संभव है (अर्थात उपरोक्त उदाहरण का उपयोग करके)

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

#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)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.