def callMethod(cls, method_name: str, signature: str, *args, service_path: str = DefaultServicePath, object_path: str = DefaultObjectPath, interface: str = DefaultInterface) -> Any: cls.__ensureDBusSetup() assert cls.__connection is not None if cls.__use_qt: message = QDBusMessage.createMethodCall(service_path, object_path, interface, method_name) message.setArguments(args) result = QDBusReply(cls.__connection.call(message)) if result.isValid(): return result.value() else: log.warning("Did not receive a valid reply for method call %s", method_name) log.warning(result.error().message()) return None else: return cls.__connection.call_blocking(service_path, object_path, interface, method_name, signature, args)
def main(): import sys app = QCoreApplication(sys.argv) # noqa: F841 if not QDBusConnection.sessionBus().isConnected(): sys.stderr.write("Cannot connect to the D-Bus session bus.\n" "To start it, run:\n" "\teval `dbus-launch --auto-syntax`\n") sys.exit(1) iface = QDBusInterface(SERVICE_NAME, "/", "", QDBusConnection.sessionBus()) if iface.isValid(): msg = iface.call("ping", sys.argv[1] if len(sys.argv) > 1 else "") reply = QDBusReply(msg) if reply.isValid(): sys.stdout.write("Reply was: %s\n" % reply.value()) sys.exit() sys.stderr.write("Call failed: %s\n" % reply.error().message()) sys.exit(1) sys.stderr.write("%s\n" % QDBusConnection.sessionBus().lastError().message()) sys.exit(1)
def inhibit(self): msg = self.call("Inhibit", "DMovie", "Video Playing!") reply = QDBusReply(msg) if reply.isValid(): self._inhibit_cookie = reply.value() return self._inhibit_cookie else: return None
def _call(self, method, *args): msg = self.cache.call(method, *args) reply = QDBusReply(msg) if not reply.isValid(): raise Exception("Error on method call '{}': {}: {}".format( method, reply.error().name(), reply.error().message())) else: return msg.arguments()
def call(obj, method, *args): msg = obj.call(method, *args) reply = QDBusReply(msg) if not reply.isValid(): raise Exception("Error on method call '{}': {}: {}".format( method, reply.error().name(), reply.error().message())) else: return msg.arguments()
def notify(self, summary, body, actions=[]): varRPlaceId = QVariant(0) varRPlaceId.convert(QVariant.UInt) varActions = QVariant(actions) varActions.convert(QVariant.StringList) msg = self.call("Notify", "Deepin Screenshot", varRPlaceId, "deepin-screenshot", summary, body, varActions, {}, -1) reply = QDBusReply(msg) return reply.value()
def showRectMenu(self, x, y): msg = self.managerIface.registerMenu() reply = QDBusReply(msg) self.menuIface = MenuObjectInterface(reply.value()) self.menuIface.showMenu(json.dumps({"x": x, "y": y, "isDockMenu": False, "menuJsonContent": str(self)})) self.menuIface.ItemInvoked.connect(self.itemInvokedSlot) self.menuIface.MenuUnregistered.connect(self.menuUnregisteredSlot)
def notify(self, summary, body): replaceId = QVariant(0) replaceId.convert(QVariant.UInt) actions = QVariant([]) actions.convert(QVariant.StringList) msg = self.call("Notify", "Deepin Movie", replaceId, "deepin-movie", summary, body, actions, {}, -1) reply = QDBusReply(msg) return reply.value if reply.isValid() else None
def showDockMenu(self, x, y, cornerDirection="down"): msg = self.managerIface.registerMenu() reply = QDBusReply(msg) self.menuIface = MenuObjectInterface(reply.value()) self.menuIface.showMenu(json.dumps({"x": x, "y": y, "isDockMenu": True, "cornerDirection": cornerDirection, "menuJsonContent": str(self)})) self.menuIface.ItemInvoked.connect(self.itemInvokedSlot) self.menuIface.MenuUnregistered.connect(self.menuUnregisteredSlot)
def inhibitScreenlock(self): if not QDBusConnection.sessionBus().isConnected(): sys.stderr.write("Cannot connect to the D-Bus session bus.\n" "To start it, run:\n" "\teval `dbus-launch --auto-syntax`\n"); return iface = QDBusInterface('org.kde.screensaver', '/ScreenSaver', '', QDBusConnection.sessionBus()) if iface.isValid(): msg = iface.call('Inhibit', 'DisUpgradeViewKDE', 'Upgrading base OS') reply = QDBusReply(msg) self.screenLockCookie = reply.value()
def __onAsyncCallFinished(self, watcher): assert watcher in self.__pending_async_calls success_callback = self.__pending_async_calls[watcher][0] error_callback = self.__pending_async_calls[watcher][1] del self.__pending_async_calls[watcher] reply = QDBusReply(watcher) if reply.isValid(): if success_callback: success_callback(reply.value()) else: if error_callback: error_callback(reply.error().message())
def notify(self, summary, body): replaceId = QVariant(0) replaceId.convert(QVariant.UInt) actions = QVariant([]) actions.convert(QVariant.StringList) msg = self.call( "Notify", "Deepin Movie", replaceId, "deepin-movie", summary, body, actions, {}, -1) reply = QDBusReply(msg) return reply.value if reply.isValid() else None
def notify(self, summary, body, actions=[], hints={}): varRPlaceId = QVariant(0) varRPlaceId.convert(QVariant.UInt) varActions = QVariant(actions) varActions.convert(QVariant.StringList) varHints = QVariant(hints) varHints.convert(QVariant.Map) msg = self.call("Notify", "Deepin Screenshot", varRPlaceId, "deepin-screenshot", summary, body, varActions, varHints, -1) reply = QDBusReply(msg) if reply.isValid(): return reply.value() else: return None
def callSync(self, *args, warnWhenCallIsSlow=True, **kwargs): """Call a camera DBus API. First arg is the function name. This is the synchronous version of the call() method. It is much slower to call synchronously than asynchronously! See http://doc.qt.io/qt-5/qdbusabstractinterface.html#call for details about calling. See https://github.com/krontech/chronos-cli/tree/master/src/api for implementation details about the API being called. See README.md at https://github.com/krontech/chronos-cli/tree/master/src/daemon for API documentation. """ #Unwrap D-Bus errors from message. log.debug("%s.callSync %s", self.name, tuple(args)) start = perf_counter() msg = QDBusReply(self.iface.call(*args, **kwargs)) end = perf_counter() if warnWhenCallIsSlow and (end - start > API_SLOW_WARN_MS / 1000): log.warn(f'slow call: {self.name}.callSync{tuple(args)} took {(end-start)*1000:.0f}ms/{API_SLOW_WARN_MS}ms.') if msg.isValid(): return msg.value() else: if msg.error().name() == 'org.freedesktop.DBus.Error.NoReply': raise DBusException(f"{self.name}.callSync{tuple(args)} timed out ({API_TIMEOUT_MS}ms)") else: raise DBusException("%s: %s" % (msg.error().name(), msg.error().message()))
def __rescan(self): self._connections.clear() for interfaces in self._networkInterfaces: carrier = QDBusReply( interfaces['Device property interface'].call('Get', 'org.freedesktop.NetworkManager.Device.Wired', 'Carrier' ) ) #Interface, Property if carrier.isValid() and carrier.value(): try: addr = IPv4Address( QDBusReply( interfaces['Device property interface'].call( 'Get', #Method 'org.freedesktop.NetworkManager.Device', #Interface 'Ip4Address', #Property ) ).value() ) addr = IPv4Address('.'.join(reversed(str(addr).split('.')))) #So close. Truly, if there's two ways of representing information… (note: This is actually Python's fault here, the number parses fine in a browser address bar.) except AddressValueError: try: #"Array of tuples of IPv4 address/prefix/gateway. All 3 elements of each tuple are in network byte order. Essentially: [(addr, prefix, gateway), (addr, prefix, gateway), ...]" # -- https://developer.gnome.org/NetworkManager/0.9/spec.html addr = IPv6Address(bytes( QDBusReply( interfaces['Ip6Config property interface'].call( 'Get', #Method 'org.freedesktop.NetworkManager.IP6Config', #Interface 'Addresses', #Property ) ).value()[-1][0] )) except (AddressValueError, IndexError): addr = None interface = QDBusReply( interfaces['Device property interface'].call( 'Get', #Method 'org.freedesktop.NetworkManager.Device', #Interface 'Interface', #Property ) ).value() if addr: self._connections.append({ 'path': interfaces['Device'].path(), 'name': defaultdict( lambda: 'generic connection', {'e': 'ethernet', 'u': 'usb'} )[interface[0]], 'address': addr, }) log.info(f'conns: {self._connections}') for callback in self._callbacks: callback(self._connections)
def video(*args, **kwargs): """ Call the camera video DBus API. First arg is the function name. See http://doc.qt.io/qt-5/qdbusabstractinterface.html#call for details about calling. See https://github.com/krontech/chronos-cli/tree/master/src/api for implementation details about the API being called. See README.md at https://github.com/krontech/chronos-cli/tree/master/src/daemon for API documentation. """ msg = QDBusReply(cameraVideoAPI.call(*args, **kwargs)) if not msg.isValid(): raise DBusException("%s: %s" % (msg.error().name(), msg.error().message())) return msg.value()
from PyQt5.QtCore import QCoreApplication from PyQt5.QtDBus import QDBusConnection, QDBusInterface, QDBusReply if __name__ == "__main__": app = QCoreApplication(sys.argv) if not QDBusConnection.sessionBus().isConnected(): sys.stderr.write("Cannot connect to the D-Bus session bus.\n" "To start it, run:\n" "\teval `dbus-launch --auto-syntax`\n") sys.exit(1) iface = QDBusInterface("org.example.QtDBus.PingExample", "/", "", QDBusConnection.sessionBus()) if iface.isValid(): msg = iface.call("ping", sys.argv[1] if len(sys.argv) > 1 else "") reply = QDBusReply(msg) if reply.isValid(): sys.stdout.write("Reply was: %s\n" % reply.value()) sys.exit() sys.stderr.write("Call failed: %s\n" % reply.error().message()) sys.exit(1) sys.stderr.write("%s\n" % QDBusConnection.sessionBus().lastError().message()) sys.exit(1)
def _acquireInterfaceData(self, reply): """Continuation of __init__. [DDR 2019-11-05] Note: In Qt 5.7, we can't just go self._networkInterfaces['Device'].property(), like we could with self._networkInterfaces['Device'].call(), because .property() doesn't seem to work. afaik, it _should_ work, and the example in https://stackoverflow.com/questions/20042995/error-getting-dbus-interface-property-with-qdbusinterface which is directly relevant to our situation shows it working. Yet, I cannot figure out how to port it to Python. So we do it manually with the `'* property interface'`s. Note: https://doc.qt.io/archives/qt-5.7/qnetworkinterface.html is a thing. Shame it doesn't have notification events. Command-line based examples: docs: https://developer.gnome.org/NetworkManager/0.9/spec.html org.freedesktop.NetworkManager.Device.Wired has ipv4/6 properties gdbus introspect --system --dest org.freedesktop.NetworkManager.Device.Wired --object-path /org/freedesktop/NetworkManager/Device/Wired - Get network interfaces: > gdbus introspect --system --dest org.freedesktop.NetworkManager --object-path /org/freedesktop/NetworkManager - Has ActivateConnection method in org.freedesktop.NetworkManager - Has GetDevices method in org.freedesktop.NetworkManager > gdbus call --system --dest org.freedesktop.NetworkManager --object-path /org/freedesktop/NetworkManager --method org.freedesktop.NetworkManager.GetDevices - ([objectpath '/org/freedesktop/NetworkManager/Devices/0', '/org/freedesktop/NetworkManager/Devices/1', '/org/freedesktop/NetworkManager/Devices/2', '/org/freedesktop/NetworkManager/Devices/3'],) > gdbus introspect --system --dest org.freedesktop.NetworkManager --object-path /org/freedesktop/NetworkManager/Devices/0 - This is apparently a network connection - in this case, loopback. - Links to IPv4/6 config. > gdbus introspect --system --dest org.freedesktop.NetworkManager --object-path /org/freedesktop/NetworkManager/Devices/1 - eth0 - is plugged in? - org.freedesktop.NetworkManager.Device.Wired property Carrier - [implements g interfaces] Filter org.freedesktop.NetworkManager.GetDevices to get the list of plugged-in interfaces. > gdbus introspect --system --dest org.freedesktop.NetworkManager --object-path /org/freedesktop/NetworkManager/DHCP4Config/0 - yields org.freedesktop.NetworkManager.DHCP4Config - from ip_address' Dhcp4Config property - [implements g n lan IPv4 or v6] in properties & PropertiesChanged signal. > gdbus introspect --system --dest org.freedesktop.NetworkManager --object-path /org/freedesktop/NetworkManager/IP6Config/2 - yields org.freedesktop.NetworkManager.IP6Config - from ip_address' Ip6Config property - [implements g n g n www IPv4 or v6] in Addresses (first item) & PropertiesChanged signal. - has Disconnect method - https://developer.gnome.org/NetworkManager/0.9/spec.html#org.freedesktop.NetworkManager.Device.Disconnect > gdbus introspect --system --dest org.freedesktop.NetworkManager --object-path /org/freedesktop/NetworkManager/Devices/2 - eth1 > gdbus introspect --system --dest org.freedesktop.NetworkManager --object-path /org/freedesktop/NetworkManager/Devices/3 - usb0 """ reply = QDBusPendingReply(reply) if reply.isError(): raise DBusException("%s: %s" % (reply.error().name(), reply.error().message())) reply = reply.value() self._networkInterfaces = [{ 'Device': QDBusInterface( #Provides node. f"org.freedesktop.NetworkManager", #Service devicePath, #Path f"org.freedesktop.NetworkManager.Device", #Interface QDBusConnection.systemBus(), ), 'Device.Wired': QDBusInterface( #Provides node. f"org.freedesktop.NetworkManager", #Service devicePath, #Path f"org.freedesktop.NetworkManager.Device.Wired", #Interface QDBusConnection.systemBus(), ), 'Device property interface': QDBusInterface( #Provides interface to get properties of previous node, because `.property()` is broken. "org.freedesktop.NetworkManager", #Service devicePath, #Path "org.freedesktop.DBus.Properties",#Interface QDBusConnection.systemBus() ), } for devicePath in reply ] for interfaces in self._networkInterfaces: for networkInterface in interfaces.values(): networkInterface.setTimeout(1000) if not networkInterface.isValid(): log.critical(f"Error: Can not connect to NetworkManager at {networkInterface.service()}. ({networkInterface.lastError().name()}: {networkInterface.lastError().message()}) Try running `apt install network-manager`?") raise Exception("D-Bus Setup Error") #Deadlock fix as above. QDBusConnection.systemBus().registerObject( interfaces['Device'].path(), self ) #Use above interface to look up the IP address interfaces. interfaces['Ip4Config'] = QDBusInterface( #Provides interface to get properties of previous node, because `.property()` is broken. "org.freedesktop.NetworkManager", #Service QDBusReply(interfaces['Device property interface'].call('Get', #Method 'org.freedesktop.NetworkManager.Device', 'Ip4Config' )).value(), #Interface, Property → Path "org.freedesktop.NetworkManager.IP4Config", #Interface QDBusConnection.systemBus() ) interfaces['Ip4Config property interface'] = QDBusInterface( #Provides interface to get properties of previous node, because `.property()` is broken. "org.freedesktop.NetworkManager", #Service interfaces['Ip4Config'].path(), #Path "org.freedesktop.DBus.Properties",#Interface QDBusConnection.systemBus() ) interfaces['Ip6Config'] = QDBusInterface( #Provides interface to get properties of previous node, because `.property()` is broken. "org.freedesktop.NetworkManager", #Service QDBusReply(interfaces['Device property interface'].call('Get', #Method 'org.freedesktop.NetworkManager.Device', 'Ip6Config' )).value(), #Interface, Property → Path "org.freedesktop.NetworkManager.IP6Config", #Interface QDBusConnection.systemBus() ) interfaces['Ip6Config property interface'] = QDBusInterface( #Provides interface to get properties of previous node, because `.property()` is broken. "org.freedesktop.NetworkManager", #Service interfaces['Ip6Config'].path(), #Path "org.freedesktop.DBus.Properties",#Interface QDBusConnection.systemBus() ) #Subscribe to network update signals, for ip address and carrier status. QDBusConnection.systemBus().connect( f"org.freedesktop.NetworkManager", #Service interfaces['Device'].path(), f"org.freedesktop.NetworkManager.Device", #Interface 'PropertiesChanged', #Signal self.__interfacePropertiesChangedEvent, ) QDBusConnection.systemBus().connect( f"org.freedesktop.NetworkManager", #Service interfaces['Device'].path(), f"org.freedesktop.NetworkManager.Device.Wired", #Interface 'PropertiesChanged', #Signal self.__interfacePropertiesChangedEvent, ) QDBusConnection.systemBus().connect( #untested, don't know how to change ip4 address f"org.freedesktop.NetworkManager", #Service QDBusReply(interfaces['Device property interface'].call('Get', 'org.freedesktop.NetworkManager.Device', 'Dhcp4Config' ) ).value(), #Interface, Property → Path f"org.freedesktop.NetworkManager.Dhcp4Config", #Interface 'PropertiesChanged', #Signal self.__interfacePropertiesChangedEvent, ) QDBusConnection.systemBus().connect( #untested, don't know how to change ip6 address f"org.freedesktop.NetworkManager", #Service QDBusReply(interfaces['Device property interface'].call('Get', 'org.freedesktop.NetworkManager.Device', 'Dhcp6Config' ) ).value(), #Interface, Property → Path f"org.freedesktop.NetworkManager.Dhcp6Config", #Interface 'PropertiesChanged', #Signal self.__interfacePropertiesChangedEvent, ) self.__rescan()
def __init__(self): """ Get _partitions, a list of things you can save video to. { "name": "Testdisk", "device": "mmcblk0p1", "uuid": "a14d610d-b524-4af2-9a1a-fa3dd1184258", "path": bytes("/dev/sda", 'utf8'), "size": 1294839100, #bytes, 64-bit positive integer "readOnly": False, "interface": "usb", #"usb" or "sd" } """ super().__init__() self._partitions = [] #observers collection self._callbacks = [] self.uDisks2ObjectManager = QDBusInterface( f"org.freedesktop.UDisks2", #Service f"/org/freedesktop/UDisks2", #Path f"org.freedesktop.DBus.ObjectManager", #Interface QDBusConnection.systemBus(), ) self.uDisks2ObjectManager.setTimeout(10) #Set to 1000 after startup period. #Retry. This doesn't connect the first time, no matter what the time limit is. I don't know why, probably something in the start-on-demand logic. if not self.uDisks2ObjectManager.isValid(): self.uDisks2ObjectManager = QDBusInterface( f"org.freedesktop.UDisks2", #Service f"/org/freedesktop/UDisks2", #Path f"org.freedesktop.DBus.ObjectManager", #Interface QDBusConnection.systemBus(), ) self.uDisks2ObjectManager.setTimeout(10) if not self.uDisks2ObjectManager.isValid(): log.critical(f"Error: Can not connect to udisks2 at {self.uDisks2ObjectManager.service()}. ({self.uDisks2ObjectManager.lastError().name()}: {self.uDisks2ObjectManager.lastError().message()}) Try running `apt install udisks2`?") raise Exception("D-Bus Setup Error") self.uDisks2ObjectManager.setTimeout(1000) #The .connect call freezes if we don't do this, or if we do this twice. #This bug was fixed by Qt 5.11. QDBusConnection.systemBus().registerObject( f"/org/freedesktop/UDisks2", self, ) QDBusConnection.systemBus().connect( f"org.freedesktop.UDisks2", #Service f"/org/freedesktop/UDisks2", #Path f"org.freedesktop.DBus.ObjectManager", #Interface 'InterfacesAdded', #Signal self.__interfacesAddedEvent, ) QDBusConnection.systemBus().connect( f"org.freedesktop.UDisks2", #Service f"/org/freedesktop/UDisks2", #Path f"org.freedesktop.DBus.ObjectManager", #Interface 'InterfacesRemoved', #Signal self.__interfacesRemovedEvent, ) for name, data in QDBusReply(self.uDisks2ObjectManager.call('GetManagedObjects')).value().items(): self.__interfacesAdded(name, data)
from PyQt5.QtCore import QCoreApplication from PyQt5.QtDBus import QDBusConnection, QDBusInterface, QDBusReply if __name__ == '__main__': app = QCoreApplication(sys.argv) if not QDBusConnection.sessionBus().isConnected(): sys.stderr.write("Cannot connect to the D-Bus session bus.\n" "To start it, run:\n" "\teval `dbus-launch --auto-syntax`\n"); sys.exit(1) iface = QDBusInterface('org.example.QtDBus.PingExample', '/', '', QDBusConnection.sessionBus()) if iface.isValid(): msg = iface.call('ping', sys.argv[1] if len(sys.argv) > 1 else "") reply = QDBusReply(msg) if reply.isValid(): sys.stdout.write("Reply was: %s\n" % reply.value()) sys.exit() sys.stderr.write("Call failed: %s\n" % reply.error().message()) sys.exit(1) sys.stderr.write("%s\n" % QDBusConnection.sessionBus().lastError().message()) sys.exit(1)
def registerArea(self, x1, x2, y1, y2, flag): msg = self.call("RegisterArea", x1, x2, y1, y2, flag) print msg.errorName(), msg.errorMessage() reply = QDBusReply(msg) return reply.value()
def getPrimaryRect(self): msg = self.call("Get", "com.deepin.daemon.Display", "PrimaryRect") reply = QDBusReply(msg) return reply.value()
def getPropertyValue(self, interfaceName, propertyName): msg = self.call("Get", interfaceName, propertyName) reply = QDBusReply(msg) return reply.value()
def inhibit(self): msg = self.call("Inhibit", "DMovie", "Video Playing!") reply = QDBusReply(msg) self._inhibit_cookie = reply.value() return self._inhibit_cookie