Làm thế nào để liệt kê tất cả các đường dẫn đối tượng trong một dịch vụ dbus?


16

Đây là câu hỏi tiếp theo cho Danh sách các dịch vụ DBus có sẵn .

Mã python sau đây sẽ liệt kê tất cả các dịch vụ DBus có sẵn.

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

Làm thế nào để chúng tôi liệt kê các đường dẫn đối tượng theo các dịch vụ trong python? Sẽ ổn nếu câu trả lời không liên quan đến trăn mặc dù nó được ưa thích hơn.

Tôi đang sử dụng Ubuntu 14.04


Sẽ ổn nếu câu trả lời không liên quan đến trăn mặc dù nó được ưa thích hơn.
user768421

Câu trả lời:


15

Theo tài liệu chính thức (theo giao diện tiêu chuẩn ):

Có một số giao diện tiêu chuẩn có thể hữu ích trên các ứng dụng D-Bus khác nhau.

org.freedesktop.DBus.Introspectable

Giao diện này có một phương thức:

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

Các thể hiện đối tượng có thể thực hiện Introspecttrả về một mô tả XML của đối tượng, bao gồm các giao diện của nó (với các tín hiệu và phương thức), các đối tượng bên dưới nó trong cây đường dẫn đối tượng và các thuộc tính của nó.

Vì vậy, đây là một ví dụ rất đơn giản sẽ giúp bạn bắt đầu. Nó sử dụng 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')

Nó đệ quy nội tâm org.freedesktop.UPowerbắt đầu từ ví dụ /org/freedesktop/UPowervà in tất cả các đường dẫn đối tượng (tên nút):

/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

đó là khá nhiều những gì bạn nhận được nếu bạn sử dụng d-feet(không phải là bạn cần nó):

nhập mô tả hình ảnh ở đây


Chắc chắn, bạn có thể dễ dàng nhận được các đường dẫn đối tượng thông qua dòng lệnh, ví dụ như với gdbus:

gdbus introspect --system --dest org.freedesktop.UPower --object-path \
/ org / freedesktop / UPower --recurse | awk '/ ^ * nút / {in $ 2}'
/ org / freedesktop / UPower
/ org / freedesktop / UPower / Wakeup
/ org / freedesktop / UPower / thiết bị
/ org / freedesktop / UPower / thiết bị / DisplayDevice
/ org / freedesktop / UPower / thiết bị / pin_BAT0
/ org / freedesktop / UPower / thiết bị / line_power_ADP0

Tôi chưa qdbuscài đặt nhưng theo trang này

qdbus --system org.freedesktop.UPower

nên tạo ra một kết quả tương tự.


Làm thế nào để tôi tạo một danh sách các đường dẫn đối tượng từ rec_intro(bus, 'org.freedesktop.UPower', '/org/freedesktop/UPower')?
Khurshid Alam

Không, ý tôi là tạo một danh sách python của các đường dẫn đối tượng, để tôi có thể kiểm tra (trong tập lệnh của mình) nếu đường dẫn đối tượng cụ thể tồn tại trong danh sách. Nó in đối tượng ổn., Nhưng tôi muốn một cái gì đó như thế k = rec_intro(bus, 'org.freedesktop.UPower', '/org/freedesktop/UPower'). Tôi cho rằng nó có thể bằng cách sửa đổi chức năng một chút.
Khurshid Alam

Mã ví dụ với qbus: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
Khurshid Alam

@KhurshidAlam - khởi tạo một danh sách trước khi chức năng ví dụ mylist=[]sau đó thay thế printvới mylist.appendvà sau đó là lệnh cuối cùng trong đó khối chức năng return mylist- đó là khá nhiều đó là những gì ... bạn có thể sau đó lặp trên danh sách hoặc bất cứ điều gì như add ở dưới cùng của kịch bản for x in mylist: print("OBJ_PATH", x)để chúng được in với OBJ_PATHtiền tố ...
don_crissti

4

Tôi không chắc bạn có thể làm điều này bằng lập trình trong Python. Bạn có thể nhưng sẽ rất đau đầu để tìm ra cách. Tôi đã cố gắng làm điều đó trước đây và cuối cùng ghét Dbus. Dù sao tôi khuyên bạn nên sử dụng d-feet nếu bạn muốn điều tra mọi thứ. Dưới đây là một ảnh chụp màn hình mà tôi đã đánh cắp từ blog của tôi .

nhập mô tả hình ảnh ở đây

Khi bạn biết tên chương trình, đường dẫn đối tượng, v.v., bạn có thể sử dụng Python để truy cập vào những thứ đó.

Thí dụ

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

Như bạn thấy, đó là một nỗi đau ở mông để hoàn thành một việc đơn giản. Nhưng đây là quy trình làm việc dễ dàng nhất bạn có thể nhận được với Dbus!

Vì vậy, sử dụng một công cụ GUI để tìm ra các đường dẫn đối tượng, giao diện, v.v. Sau đó, sử dụng đoạn mã ở trên làm mẫu để truy cập vào những thứ đó. Ngoài ra tôi khuyên bạn nên làm điều này thông qua trình thông dịch của IPython để xem phương thức, thuộc tính, v.v. mỗi đối tượng có (bằng cách nhấn tab).



1

Những gì tôi biết từ kinh nghiệm của mình để có được các đường dẫn đối tượng của tên xe buýt (dịch vụ) có thể hướng nội với đường dẫn đối tượng '/' tức là (sử dụng ví dụ trên)

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

điều này sẽ trở lại:

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

sau đó hướng nội với đường dẫn '/ org'

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

điều này sẽ trở lại:

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

và như thế:

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

Nó giống như đi qua cấu trúc thư mục của ổ cứng trong đó đường dẫn đối tượng '/' là gốc và mọi nút là thư mục con. Đây có vẻ là cách tốt nhất để truy xuất các đường dẫn đối tượng của một tên bus (dịch vụ) cụ thể và để xây dựng một bộ sưu tập chứa các đường dẫn đối tượng


1

Theo câu trả lời của #don_crissti , tôi đã triển khai, Giải pháp này cung cấp cho tên giao diện và phương thức và thông tin tín hiệu

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.