def unmount_usb_device(block_device: str): """ Attempts to unmount a USB device via org.freedesktop.UDisks2.Filesystem D-Bus interface as described at http://storaged.org/doc/udisks2-api/latest/gdbus-org.freedesktop.UDisks2.Filesystem.html#gdbus-method-org-freedesktop-UDisks2-Filesystem.Unmount. :param block_device: a partition name to unmount, for example /dev/sdb1 """ if block_device is None: raise TypeError("'block_device' cannot be of type 'NoneType'") elif block_device == '': raise ValueError("'block_device' cannot be empty") path = block_device.replace('/dev', '/org/freedesktop/UDisks2/block_devices') file_system_interface = QDBusInterface( 'org.freedesktop.UDisks2', path, 'org.freedesktop.UDisks2.Filesystem', QDBusConnection.systemBus()) if not file_system_interface.isValid(): raise RuntimeError(_translate('DriveUtils', 'Invalid D-Bus interface')) reply = file_system_interface.call('Unmount', {}) if reply.type() == QDBusMessage.ErrorMessage: raise RuntimeError(reply.errorMessage()) elif reply.type() != QDBusMessage.ReplyMessage: raise RuntimeError( _translate('DriveUtils', 'Unexpected reply from Udisks'))
def __init__(self, bus, listener=None): super().__init__() self.bus = bus self.bus.registerObject('/', self) self.requests: Dict[str, Tuple[str, str, str]] = {} self.thumbnailer = QDBusInterface( 'org.freedesktop.thumbnails.Thumbnailer1', '/org/freedesktop/thumbnails/Thumbnailer1', 'org.freedesktop.thumbnails.Thumbnailer1', connection=self.bus) self.listener = listener self.bus.connect('', '', 'org.freedesktop.thumbnails.Thumbnailer1', 'Ready', self._receive_ready) self.bus.connect('', '', 'org.freedesktop.thumbnails.Thumbnailer1', 'Started', self._receive_started) self.bus.connect('', '', 'org.freedesktop.thumbnails.Thumbnailer1', 'Finished', self._receive_finished) self.bus.connect('', '', 'org.freedesktop.thumbnails.Thumbnailer1', 'Error', self._receive_error)
def packagekit_install(pack="ffmpeg"): """ Equivalent of: qdbus org.freedesktop.PackageKit /org/freedesktop/PackageKit org.freedesktop.PackageKit.Modify.InstallPackageNames 0 ffmpeg "show-confirm-search,hide-finished" Or: qdbus org.freedesktop.PackageKit /org/freedesktop/PackageKit org.freedesktop.PackageKit.Query.IsInstalled 0 ffmpeg See also (dbus) http://www.freedesktop.org/software/PackageKit/pk-faq.html#session-methods Doc: http://blog.fpmurphy.com/2013/11/packagekit-d-bus-abstraction-layer.html """ from PyQt5.QtDBus import QDBusConnection from PyQt5.QtDBus import QDBusInterface bus = QDBusConnection.sessionBus() service_name = "org.freedesktop.PackageKit" service_path = "/org/freedesktop/PackageKit" interface = "org.freedesktop.PackageKit.Query.IsInstalled" install = QDBusInterface(service_name, service_path, interface, bus) reply = install.call(0, pack, "show-confirm-search,hide-finished") print(reply.arguments()) interface = "org.freedesktop.PackageKit.Modify.InstallPackageNames" install = QDBusInterface(service_name, service_path, interface, bus) reply = install.call(0, pack, "show-confirm-search,hide-finished") print(reply.arguments())
def _dbus_notify(title, message, duration=5000): from PyQt5.QtDBus import ( QDBus, QDBusArgument, QDBusConnection, QDBusInterface) bus = QDBusConnection.sessionBus() if not bus.isConnected(): raise OSError("Could not connect to DBus") interface = QDBusInterface( 'org.freedesktop.Notifications', '/org/freedesktop/Notifications', 'org.freedesktop.Notifications', bus) error = interface.lastError() if error.type(): raise RuntimeError("{}; {}".format(error.name(), error.message())) # See https://developer.gnome.org/notification-spec/ # "This allows clients to effectively modify the notification while # it's active. A value of value of 0 means that this notification # won't replace any existing notifications." replaces_id = QVariant(0) replaces_id.convert(QVariant.UInt) interface.call( QDBus.NoBlock, 'Notify', APP_NAME, replaces_id, resource(settings['application']['tray_icon']), title, message, QDBusArgument([], QMetaType.QStringList), {}, duration)
def __init__(self, qobject): ''' Starts the d-bus service to watch for any stray notifications ''' super().__init__(qobject) sb = QDBusConnection.sessionBus() print("Notifs_Dbus: Registering notif. service…") try: sb.registerService("org.freedesktop.Notifications") except: print("Couldn't register freedesktop notifications service!") print("Notifs_Dbus: Registering notif. object…") try: sb.registerObject("/org/freedesktop/Notifications", qobject) except: print("Couldn't register freedesktop notifications object!") # match string m = "eavesdrop='true', interface='org.freedesktop.Notifications', member='Notify', type='method_call'" i = QDBusInterface("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus") i.call("AddMatch", m) print("Notifs_Dbus: Listener should start by now.")
def __init__(self, *, taskModel, frontendSettings, parent): super().__init__(parent) self.__taskModel = taskModel self.__frontendSettings = frontendSettings self._conn = QDBusConnection("Xware Desktop").sessionBus() self._interface = QDBusInterface(_DBUS_NOTIFY_SERVICE, _DBUS_NOTIFY_PATH, _DBUS_NOTIFY_INTERFACE, self._conn) self._notified = {} # a dict of notifyId: taskDict self.__taskModel.taskCompleted.connect(self.notifyTaskCompleted, Qt.DirectConnection) self._capabilities = self._getCapabilities() if "actions" in self._capabilities: successful = self._conn.connect(_DBUS_NOTIFY_SERVICE, _DBUS_NOTIFY_PATH, _DBUS_NOTIFY_INTERFACE, "ActionInvoked", self.slotActionInvoked) if not successful: logging.error("ActionInvoked connect failed.") self._qSound_complete = QSound(":/sound/download-complete.wav", self)
def __init__(self, application): super().__init__(application) self.__sessionService = application.sessionService self.__settings = application.settings self._menubarAdapter = CanonicalDBusMenuAdapter( sessionService=self.__sessionService, settings=self.__settings, app=application, parent=self, ) self.__sessionService.registerObject( "/MenuBar", self._menubarAdapter, ) self._sniAdapter = KdeStatusNotifierAdapter( sessionService=self.__sessionService, parent=self, ) self.__sessionService.registerObject( "/StatusNotifierItem", self._sniAdapter, ) self._interface = QDBusInterface( "org.kde.StatusNotifierWatcher", "/StatusNotifierWatcher", "org.kde.StatusNotifierWatcher", )
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)
class PowerActionManager(QObject): def __init__(self, parent = None): # manages power actions, and act them. super().__init__(parent) self._conn = QDBusConnection("Xware Desktop").systemBus() self._interface = QDBusInterface(_DBUS_POWER_SERVICE, _DBUS_POWER_PATH, _DBUS_POWER_INTERFACE, self._conn) self._actions = {} # {Action: ActionType} self._loadActions() def _loadActions(self): for action in Action: # Always allow Null action if action == Action.Null: self._actions[action] = ActionType.Special continue # check if cmd is set internalName = action.name if app.settings.has("scheduler", internalName + "cmd"): self._actions[action] = ActionType.Command continue # check if logind supports it msg = self._interface.call("Can" + internalName) if msg.errorName(): logging.error(msg.errorMessage()) availability = msg.arguments()[0] if availability == "yes": self._actions[action] = ActionType.DBus continue @property def actions(self) -> "listlike of actions": return self._actions.keys() def act(self, action: Action): assert isinstance(action, Action), "{} is not an Action".format(action) assert action in self._actions, "{} is not available!".format(action) actionType = self._actions.get(action, None) internalName = action.name if actionType is None: raise ValueError("{} are not supported!".format(action)) if actionType == ActionType.Special: raise ValueError("Cannot act on {}".format(action)) elif actionType == ActionType.Command: cmd = app.settings.get("scheduler", internalName + "cmd") os.system(cmd) return elif actionType == ActionType.DBus: msg = self._interface.call(internalName, False) if msg.errorName(): logging.error(msg.errorMessage()) return else: raise ValueError("Unhandled {}".format(action))
def __init__(self): """ NetworkInterfaces is a list of the plugged-in network connections. ```python [{ "path": b"/org/freedesktop/NetworkManager/Devices/1" "name": "Ethernet", "address": "192.168.100.166" or "2001:0db8:85a3::8a2e:0370:7334" }, { ... }] ``` You can `networkInterfaces.observe(callback)` to get updates. """ super().__init__() self._connections = [] #observers collection self._callbacks = [] self.networkManager = QDBusInterface( f"org.freedesktop.NetworkManager", #Service f"/org/freedesktop/NetworkManager", #Path f"org.freedesktop.NetworkManager", #Interface QDBusConnection.systemBus(), ) self.networkManager.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.networkManager.isValid(): self.networkManager = QDBusInterface( f"org.freedesktop.NetworkManager", #Service f"/org/freedesktop/NetworkManager", #Path f"org.freedesktop.NetworkManager", #Interface QDBusConnection.systemBus(), ) self.networkManager.setTimeout(10) if not self.networkManager.isValid(): log.critical(f"Error: Can not connect to NetworkManager at {self.networkManager.service()}. ({self.networkManager.lastError().name()}: {self.networkManager.lastError().message()}) Try running `apt install network-manager`?") raise Exception("D-Bus Setup Error") self.networkManager.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/NetworkManager", self, ) self._acquireInterfacesCall = QDBusPendingCallWatcher( self.networkManager.asyncCall('GetDevices') ) self._acquireInterfacesCall.finished.connect(self._acquireInterfaceData)
def __init__(self, parent=None): # manages power actions, and act them. super().__init__(parent) self._conn = QDBusConnection("Xware Desktop").systemBus() self._interface = QDBusInterface(_DBUS_POWER_SERVICE, _DBUS_POWER_PATH, _DBUS_POWER_INTERFACE, self._conn) self._actions = {} # {Action: ActionType} self._loadActions()
def __init__(self): QtCore.QObject.__init__(self) self.session_bus = QDBusConnection.sessionBus() self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'MenuItemClicked', self.MenuItemClickedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'CheckMenuItemClicked', self.CheckMenuItemClickedSlot) self._iface = QDBusInterface(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, self.session_bus)
def __init__(self, parent: QObject = None) -> None: super().__init__(bridge) if not qtutils.version_check('5.14'): raise Error("Notifications are not supported on Qt < 5.14") if utils.is_windows: # The QDBusConnection destructor seems to cause error messages (and # potentially segfaults) on Windows, so we bail out early in that case. # We still try to get a connection on macOS, since it's theoretically # possible to run DBus there. raise Error("libnotify is not supported on Windows") bus = QDBusConnection.sessionBus() if not bus.isConnected(): raise Error( "Failed to connect to DBus session bus: " + self._dbus_error_str(bus.lastError())) self._watcher = QDBusServiceWatcher( self.SERVICE, bus, QDBusServiceWatcher.WatchForUnregistration, self, ) self._watcher.serviceUnregistered.connect( # type: ignore[attr-defined] self._on_service_unregistered) test_service = 'test-notification-service' in objects.debug_flags service = self.TEST_SERVICE if test_service else self.SERVICE self.interface = QDBusInterface(service, self.PATH, self.INTERFACE, bus) if not self.interface.isValid(): raise Error( "Could not construct a DBus interface: " + self._dbus_error_str(self.interface.lastError())) connections = [ ("NotificationClosed", self._handle_close), ("ActionInvoked", self._handle_action), ] for name, func in connections: if not bus.connect(service, self.PATH, self.INTERFACE, name, func): raise Error( f"Could not connect to {name}: " + self._dbus_error_str(bus.lastError())) self._quirks = _ServerQuirks() if not test_service: # Can't figure out how to make this work with the test server... # https://www.riverbankcomputing.com/pipermail/pyqt/2021-March/043724.html self._get_server_info() if self._quirks.skip_capabilities: self._capabilities = _ServerCapabilities.from_list([]) else: self._fetch_capabilities()
class KdeSystemTrayIcon(QObject): activated = pyqtSignal(QSystemTrayIcon.ActivationReason) def __init__(self, application): super().__init__(application) self.__sessionService = application.sessionService self.__settings = application.settings self._menubarAdapter = CanonicalDBusMenuAdapter( sessionService=self.__sessionService, settings=self.__settings, app=application, parent=self, ) self.__sessionService.registerObject( "/MenuBar", self._menubarAdapter, ) self._sniAdapter = KdeStatusNotifierAdapter( sessionService=self.__sessionService, parent=self, ) self.__sessionService.registerObject( "/StatusNotifierItem", self._sniAdapter, ) self._interface = QDBusInterface( "org.kde.StatusNotifierWatcher", "/StatusNotifierWatcher", "org.kde.StatusNotifierWatcher", ) # Implement necessary interface to mimic QSystemTrayIcon def setIcon(self, qIcon: QIcon): # extract QIcon's name iconName = qIcon.name() if not iconName: raise ValueError("only support theme icon.") self._sniAdapter.setIconName(iconName) def setContextMenu(self, qMenu: QMenu): pass def setVisible(self, visible: bool): if visible: self._interface.call( "RegisterStatusNotifierItem", QDBusArgument(self.__sessionService.serviceName, QMetaType.QString), ) else: # Maybe try unregistering the whole object? raise NotImplementedError( "UnregisterStatusNotifierItem method doesn't exist.")
class PowerActionManager(QObject): def __init__(self, parent=None): # manages power actions, and act them. super().__init__(parent) self._conn = QDBusConnection("Xware Desktop").systemBus() self._interface = QDBusInterface(_DBUS_POWER_SERVICE, _DBUS_POWER_PATH, _DBUS_POWER_INTERFACE, self._conn) self._actions = {} # {Action: ActionType} self._loadActions() def _loadActions(self): for action in Action: # Always allow Null action if action == Action.Null: self._actions[action] = ActionType.Special continue # check if cmd is set internalName = action.name if app.settings.has("scheduler", internalName + "cmd"): self._actions[action] = ActionType.Command continue # check if logind supports it msg = self._interface.call("Can" + internalName) if msg.errorName(): logging.error(msg.errorMessage()) availability = msg.arguments()[0] if availability == "yes": self._actions[action] = ActionType.DBus continue @property def actions(self) -> "listlike of actions": return self._actions.keys() def act(self, action: Action): assert isinstance(action, Action), "{} is not an Action".format(action) assert action in self._actions, "{} is not available!".format(action) actionType = self._actions.get(action, None) internalName = action.name if actionType is None: raise ValueError("{} are not supported!".format(action)) if actionType == ActionType.Special: raise ValueError("Cannot act on {}".format(action)) elif actionType == ActionType.Command: cmd = app.settings.get("scheduler", internalName + "cmd") os.system(cmd) return elif actionType == ActionType.DBus: msg = self._interface.call(internalName, False) if msg.errorName(): logging.error(msg.errorMessage()) return else: raise ValueError("Unhandled {}".format(action))
def __init__(self, dbus_name, object_name): QObject.__init__(self) iface = QDBusInterface(dbus_name, object_name, '', QDBusConnection.sessionBus()) if iface.isValid(): iface.call("unique") sys.exit(1) QDBusConnection.sessionBus().registerService(dbus_name) QDBusConnection.sessionBus().registerObject(object_name, self, QDBusConnection.ExportAllSlots)
def method2(): sys.stdout.write("Method 2:\n") bus = QDBusConnection.sessionBus() dbus_iface = QDBusInterface('org.freedesktop.DBus', '/org/freedesktop/DBus', 'org.freedesktop.DBus', bus) names = dbus_iface.call('ListNames').arguments()[0] # Mimic the output from the C++ version. sys.stdout.write('QVariant(QStringList, ("%s") )\n' % '", "'.join(names))
def uninhibitScreenlock(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(): iface.call('UnInhibit', self.screenLockCookie)
def get_devices(self): devices = [] interface = QDBusInterface(self.DBUS_SERVICE, self.DBUS_PATH, 'org.freedesktop.DBus.Introspectable', self.bus) xml_str = interface.call('Introspect').arguments()[0] for child in ElementTree.fromstring(xml_str): if child.tag == 'node': devices.append(child.attrib['name']) return devices
class KdeSystemTrayIcon(QObject): activated = pyqtSignal(QSystemTrayIcon.ActivationReason) def __init__(self, application): super().__init__(application) self.__sessionService = application.sessionService self.__settings = application.settings self._menubarAdapter = CanonicalDBusMenuAdapter( sessionService = self.__sessionService, settings = self.__settings, app = application, parent = self, ) self.__sessionService.registerObject( "/MenuBar", self._menubarAdapter, ) self._sniAdapter = KdeStatusNotifierAdapter( sessionService = self.__sessionService, parent = self, ) self.__sessionService.registerObject( "/StatusNotifierItem", self._sniAdapter, ) self._interface = QDBusInterface( "org.kde.StatusNotifierWatcher", "/StatusNotifierWatcher", "org.kde.StatusNotifierWatcher", ) # Implement necessary interface to mimic QSystemTrayIcon def setIcon(self, qIcon: QIcon): # extract QIcon's name iconName = qIcon.name() if not iconName: raise ValueError("only support theme icon.") self._sniAdapter.setIconName(iconName) def setContextMenu(self, qMenu: QMenu): pass def setVisible(self, visible: bool): if visible: self._interface.call( "RegisterStatusNotifierItem", QDBusArgument(self.__sessionService.serviceName, QMetaType.QString), ) else: # Maybe try unregistering the whole object? raise NotImplementedError("UnregisterStatusNotifierItem method doesn't exist.")
def __init__(self, parent=None): super().__init__(parent) self.sessionBus = QDBusConnection.sessionBus() self._dbusInterface = QDBusInterface("org.freedesktop.DBus", "/", "org.freedesktop.DBus") if self.serviceExists(self.serviceName): raise RuntimeError("There's a DBus that has the same name.") created = self.sessionBus.registerService(self.serviceName) if not created: raise RuntimeError("Cannot create DBus Service.") self.registerObject("/", self)
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 install_packages(pkg_names): iface = QDBusInterface("com.linuxdeepin.softwarecenter_frontend", "/com/linuxdeepin/softwarecenter_frontend", '', QDBusConnection.sessionBus()) iface.asyncCall("install_pkgs", pkg_names) iface.asyncCall("show_page", "install") iface.asyncCall("raise_to_top")
def __init__(self, application): super().__init__(application) self.__sessionService = application.sessionService self.__settings = application.settings self._menubarAdapter = CanonicalDBusMenuAdapter( sessionService = self.__sessionService, settings = self.__settings, app = application, parent = self, ) self.__sessionService.registerObject( "/MenuBar", self._menubarAdapter, ) self._sniAdapter = KdeStatusNotifierAdapter( sessionService = self.__sessionService, parent = self, ) self.__sessionService.registerObject( "/StatusNotifierItem", self._sniAdapter, ) self._interface = QDBusInterface( "org.kde.StatusNotifierWatcher", "/StatusNotifierWatcher", "org.kde.StatusNotifierWatcher", )
class DBusService(QObject): def __init__(self, parent = None): super().__init__(parent) self.sessionBus = QDBusConnection.sessionBus() self._dbusInterface = QDBusInterface("org.freedesktop.DBus", "/", "org.freedesktop.DBus") if self.serviceExists(self.serviceName): raise RuntimeError("There's a DBus that has the same name.") created = self.sessionBus.registerService(self.serviceName) if not created: raise RuntimeError("Cannot create DBus Service.") self.registerObject("/", self) def registerObject(self, path: str, adapter: QObject): return self.sessionBus.registerObject( path, adapter, QDBusConnection.ExportAllSlots | QDBusConnection.ExportAllProperties | QDBusConnection.ExportAllSignals, ) @property def serviceName(self): return constants.DBUS_SESSION_SERVICE def serviceExists(self, name) -> bool: msg = self._dbusInterface.call( "ListNames", ) return name in msg.arguments()[0]
class DBusService(QObject): def __init__(self, parent=None): super().__init__(parent) self.sessionBus = QDBusConnection.sessionBus() self._dbusInterface = QDBusInterface("org.freedesktop.DBus", "/", "org.freedesktop.DBus") if self.serviceExists(self.serviceName): raise RuntimeError("There's a DBus that has the same name.") created = self.sessionBus.registerService(self.serviceName) if not created: raise RuntimeError("Cannot create DBus Service.") self.registerObject("/", self) def registerObject(self, path: str, adapter: QObject): return self.sessionBus.registerObject( path, adapter, QDBusConnection.ExportAllSlots | QDBusConnection.ExportAllProperties | QDBusConnection.ExportAllSignals, ) @property def serviceName(self): return constants.DBUS_SESSION_SERVICE def serviceExists(self, name) -> bool: msg = self._dbusInterface.call("ListNames", ) return name in msg.arguments()[0]
class ClementineDBusInterface(object): application = None session_bus_connection = None dbus_message_handler = None player_interface = None root_interface = None tracklist_interface = None def _on_message(self, msg): if msg.arguments()[0]: self.application.metadata.update(msg.arguments()[0]) self.application.render_template() def __init__(self, application): self.application = application service_name = 'org.mpris.MediaPlayer2.clementine' service_path = '/Player' interface_name = 'org.freedesktop.MediaPlayer' signal_name = 'TrackChange' self.session_bus_connection = QDBusConnection.sessionBus() self.player = QDBusInterface( service_name, service_path, interface_name, self.session_bus_connection) self._on_message(self.player.call('GetMetadata')) self.dbus_message_handler = DBusMsgHandler(self._on_message) self.session_bus_connection.connect( None, None, interface_name, signal_name, self.dbus_message_handler.handle)
def __init__(self, bus): super().__init__() bus.registerObject('/', self) bus.connect('', '', 'org.freedesktop.DBus.ObjectManager', 'InterfacesAdded', self._on_interfaces_added) bus.connect('', '', 'org.freedesktop.DBus.ObjectManager', 'InterfacesRemoved', self._on_interfaces_removed) if False: ud_objectmanager = QDBusInterface( "org.freedesktop.UDisks2", "/org/freedesktop/UDisks2", "org.freedesktop.DBus.ObjectManager", connection=bus) result = call(ud_objectmanager, "GetManagedObjects") pprint.pprint(result) self._print_blockdevices(bus) self._print_drives(bus) self.udisks_manager = QDBusInterface( "org.freedesktop.UDisks2", "/org/freedesktop/UDisks2/Manager", "org.freedesktop.UDisks2.Manager", connection=bus) self._drives: Dict[str, List[str]] = defaultdict(list) block_devices = call(self.udisks_manager, "GetBlockDevices", {})[0] for block_device in block_devices: # block_iface = QDBusInterface("org.freedesktop.UDisks2", # block_device, # "org.freedesktop.UDisks2.Block", # connection=bus) block_props = QDBusInterface("org.freedesktop.UDisks2", block_device, "org.freedesktop.DBus.Properties", connection=bus) drive = call(block_props, "Get", "org.freedesktop.UDisks2.Block", "Drive")[0] self._drives[drive].append(block_device)
def __init__(self, loaderLauncher): super().__init__(loaderLauncher) if not QDBusConnection.sessionBus().interface().isServiceRegistered(SignalTraceLoaderDBus.DBUS_SERVICE_NAME): raise DBusInterfaceError('Service {} is not registered'.format(SignalTraceLoaderDBus.DBUS_SERVICE_NAME)) self._dbusIface = QDBusInterface(SignalTraceLoaderDBus.DBUS_SERVICE_NAME, SignalTraceLoaderDBus.DBUS_OBJECT_PATH, '') if not self._dbusIface.isValid(): raise DBusInterfaceError('DBus interface is invalid') abiVersion = self._fetchABIVersion() if abiVersion[0] != self.ABI_VERSION_MAJOR or abiVersion[1] != self.ABI_VERSION_MINOR: raise DBusInterfaceError('Incompatible version od DBus interface ABI {}.{}'.format(abiVersion[0], abiVersion[1])) self._supportedFileFormats = self._fetchSupportedFormats() self._dbusIface.setTimeout(600000)
def __init__(self, parent=None): QObject.__init__(self, parent) self.ui = loadUi('keyboard.ui') self.ui.show() self.buttons = {} self.active_color = Color(0, 0, 0) self.effect_color = Color(0, 0, 0) self.color_dialog = QColorDialog() self.bus = QDBusConnection.sessionBus() tmp = self.get_devices()[0] print(f'Using service {tmp}') self.kb_leds = QDBusInterface(self.DBUS_SERVICE, self.DBUS_PATH + '/' + tmp, self.DBUS_INT_LEDS, self.bus)
def _print_drives(self, bus): udisks_manager_introspect = QDBusInterface( "org.freedesktop.UDisks2", "/org/freedesktop/UDisks2/drives", "org.freedesktop.DBus.Introspectable", connection=bus) xml_text, = call(udisks_manager_introspect, "Introspect") print(xml_text) root = ElementTree.fromstring(xml_text) for el in root.findall("./interface"): print(" ", el.attrib['name'])
def packagekit_install(pack='ffmpeg'): """ Equivalent of: qdbus org.freedesktop.PackageKit /org/freedesktop/PackageKit org.freedesktop.PackageKit.Modify.InstallPackageNames 0 ffmpeg "show-confirm-search,hide-finished" Or: qdbus org.freedesktop.PackageKit /org/freedesktop/PackageKit org.freedesktop.PackageKit.Query.IsInstalled 0 ffmpeg See also (dbus) http://www.freedesktop.org/software/PackageKit/pk-faq.html#session-methods Doc: http://blog.fpmurphy.com/2013/11/packagekit-d-bus-abstraction-layer.html """ from PyQt5.QtDBus import QDBusConnection from PyQt5.QtDBus import QDBusInterface bus = QDBusConnection.sessionBus() service_name = 'org.freedesktop.PackageKit' service_path = '/org/freedesktop/PackageKit' interface = 'org.freedesktop.PackageKit.Query.IsInstalled' install = QDBusInterface(service_name, service_path, interface, bus) reply = install.call(0, pack, 'show-confirm-search,hide-finished') print(reply.arguments()) interface = 'org.freedesktop.PackageKit.Modify.InstallPackageNames' install = QDBusInterface(service_name, service_path, interface, bus) reply = install.call(0, pack, 'show-confirm-search,hide-finished') print(reply.arguments())
def __init__(self): QtCore.QObject.__init__(self) self.session_bus = QDBusConnection.sessionBus() self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'hide', self.hideSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'ocrRecognized', self.ocrRecognizedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'strokeRecognized', self.strokeRecognizedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'ocrEnableChanged', self.ocrEnableChangedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'strokeEnableChanged', self.strokeEnableChangedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'cursorPositionChanged', self.cursorPositionChangedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'doubleCtrlReleased', self.doubleCtrlReleasedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'altPressed', self.altPressedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'ctrlPressed', self.ctrlPressedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'shiftPressed', self.shiftPressedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'altReleased', self.altReleasedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'ctrlReleased', self.ctrlReleasedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'shiftReleased', self.shiftReleasedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'keyPressed', self.keyPressedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'keyReleased', self.keyReleasedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'wheelKeyReleased', self.wheelKeyReleasedSlot) self.getword_iface = QDBusInterface(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, self.session_bus)
class YoudaoIndicator(QtCore.QObject): DBUS_NAME = "com.youdao.indicator" DBUS_PATH = "/com/youdao/indicator" DBUS_IFACE = "com.youdao.indicator" onMenuItemClicked = QtCore.pyqtSignal(str) onCheckMenuItemClicked = QtCore.pyqtSignal(str, bool) def __init__(self): QtCore.QObject.__init__(self) self.session_bus = QDBusConnection.sessionBus() self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'MenuItemClicked', self.MenuItemClickedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'CheckMenuItemClicked', self.CheckMenuItemClickedSlot) self._iface = QDBusInterface(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, self.session_bus) @QtCore.pyqtSlot(result=bool) def isExists(self): self._iface.call("Hello") return not self._iface.lastError().isValid() @QtCore.pyqtSlot(str) def MenuItemClickedSlot(self, menu_id): self.onMenuItemClicked.emit(menu_id) @QtCore.pyqtSlot(str, bool) def CheckMenuItemClickedSlot(self, menu_id, enable): self.onCheckMenuItemClicked.emit(menu_id, enable) @QtCore.pyqtSlot(bool) def SetOcrEnable(self, enable): self._iface.call("SetOcrEnable", enable) @QtCore.pyqtSlot(bool) def SetStrokeEnable(self, enable): self._iface.call("SetStrokeEnable", enable) @QtCore.pyqtSlot() def Quit(self): self._iface.call("Quit")
def __init__(self, parent): super().__init__(parent) self._conn = QDBusConnection("Xware Desktop").sessionBus() self._interface = QDBusInterface(_DBUS_NOTIFY_SERVICE, _DBUS_NOTIFY_PATH, _DBUS_NOTIFY_INTERFACE, self._conn) self._notifications = {} self._completedTasksStat = app.etmpy.completedTasksStat self._completedTasksStat.sigTaskCompleted.connect(self.notifyTask) self._capabilities = self._getCapabilities() if "actions" in self._capabilities: successful = self._conn.connect(_DBUS_NOTIFY_SERVICE, _DBUS_NOTIFY_PATH, _DBUS_NOTIFY_INTERFACE, "ActionInvoked", self.slotActionInvoked) if not successful: logging.error("ActionInvoked connect failed.") self._qSound_complete = QSound(":/sound/download-complete.wav", self)
def __init__(self, parent = None): super().__init__(parent) self.sessionBus = QDBusConnection.sessionBus() self._dbusInterface = QDBusInterface("org.freedesktop.DBus", "/", "org.freedesktop.DBus") if self.serviceExists(self.serviceName): raise RuntimeError("There's a DBus that has the same name.") created = self.sessionBus.registerService(self.serviceName) if not created: raise RuntimeError("Cannot create DBus Service.") self.registerObject("/", self)
def __grabRectangle(self): """ Private method to grab a rectangular desktop area. """ snapshot = QPixmap() if Globals.isGnomeDesktop(): # Step 1: let the user select the area interface = QDBusInterface( "org.gnome.Shell", "/org/gnome/Shell/Screenshot", "org.gnome.Shell.Screenshot" ) reply = interface.call("SelectArea") if self.__checkReply(reply, 4): x, y, width, height = reply.arguments()[:4] # Step 2: grab the selected area path = self.__temporaryFilename() reply = interface.call( "ScreenshotArea", x, y, width, height, False, path ) if self.__checkReply(reply, 2): filename = reply.arguments()[1] if filename: snapshot = QPixmap(filename) try: os.remove(filename) except OSError: # just ignore it pass self.grabbed.emit(snapshot)
def __init__(self, parent = None): super().__init__(parent) self._conn = QDBusConnection("Xware Desktop").systemBus() self._interface = QDBusInterface(_DBUS_POWER_SERVICE, _DBUS_POWER_PATH, _DBUS_POWER_INTERFACE, self._conn) self.actions = ( PowerAction(self, ACTION_NONE, "无", "None"), PowerAction(self, ACTION_POWEROFF, "关机", "PowerOff"), PowerAction(self, ACTION_HYBRIDSLEEP, "混合休眠", "HybridSleep"), PowerAction(self, ACTION_HIBERNATE, "休眠", "Hibernate"), PowerAction(self, ACTION_SUSPEND, "睡眠", "Suspend"), ) logging.info(self.actions)
class PowerActionManager(QObject): # manages power actions, and act them. _conn = None _interface = None actions = None def __init__(self, parent = None): super().__init__(parent) self._conn = QDBusConnection("Xware Desktop").systemBus() self._interface = QDBusInterface(_DBUS_POWER_SERVICE, _DBUS_POWER_PATH, _DBUS_POWER_INTERFACE, self._conn) self.actions = ( PowerAction(self, ACTION_NONE, "无", "None"), PowerAction(self, ACTION_POWEROFF, "关机", "PowerOff"), PowerAction(self, ACTION_HYBRIDSLEEP, "混合休眠", "HybridSleep"), PowerAction(self, ACTION_HIBERNATE, "休眠", "Hibernate"), PowerAction(self, ACTION_SUSPEND, "睡眠", "Suspend"), ) logging.info(self.actions) def getActionById(self, actionId): return self.actions[actionId] def act(self, actionId): action = self.getActionById(actionId) if action.command: return self._cmdAct(action) elif action.availability == "yes": return self._dbusAct(action) raise Exception("Unhandled {}".format(action)) def _dbusAct(self, action): logging.info("scheduler is about to act: {}".format(action)) msg = self._interface.call(action.internalName, False) if msg.errorName(): logging.error(msg.errorMessage()) @staticmethod def _cmdAct(action): logging.info("scheduler is about to execute: {}".format(action)) os.system(action.command)
def __init__(self, application): self.application = application service_name = 'org.mpris.MediaPlayer2.clementine' service_path = '/Player' interface_name = 'org.freedesktop.MediaPlayer' signal_name = 'TrackChange' self.session_bus_connection = QDBusConnection.sessionBus() self.player = QDBusInterface( service_name, service_path, interface_name, self.session_bus_connection) self._on_message(self.player.call('GetMetadata')) self.dbus_message_handler = DBusMsgHandler(self._on_message) self.session_bus_connection.connect( None, None, interface_name, signal_name, self.dbus_message_handler.handle)
def __init__(self, *, taskModel, frontendSettings, parent): super().__init__(parent) self.__taskModel = taskModel self.__frontendSettings = frontendSettings self._conn = QDBusConnection("Xware Desktop").sessionBus() self._interface = QDBusInterface(_DBUS_NOTIFY_SERVICE, _DBUS_NOTIFY_PATH, _DBUS_NOTIFY_INTERFACE, self._conn) self._notified = {} # a dict of notifyId: taskDict self.__taskModel.taskCompleted.connect(self.notifyTaskCompleted, Qt.DirectConnection) self._capabilities = self._getCapabilities() if "actions" in self._capabilities: successful = self._conn.connect( _DBUS_NOTIFY_SERVICE, _DBUS_NOTIFY_PATH, _DBUS_NOTIFY_INTERFACE, "ActionInvoked", self.slotActionInvoked ) if not successful: logging.error("ActionInvoked connect failed.") self._qSound_complete = QSound(":/sound/download-complete.wav", self)
def __init__(self, parent): super().__init__(parent) self._conn = QDBusConnection("Xware Desktop").sessionBus() self._interface = QDBusInterface(_DBUS_NOTIFY_SERVICE, _DBUS_NOTIFY_PATH, _DBUS_NOTIFY_INTERFACE, self._conn) self._notifications = {} self._completedTasksStat = app.etmpy.completedTasksStat self._completedTasksStat.sigTaskCompleted.connect(self.notifyTask) successful = self._conn.connect(_DBUS_NOTIFY_SERVICE, _DBUS_NOTIFY_PATH, _DBUS_NOTIFY_INTERFACE, "ActionInvoked", self.slotActionInvoked) if not successful: logging.error("ActionInvoked connect failed.") self._qSound_complete = QSound(":/sound/download-complete.wav", self)
def __init__(self, dbus_name, object_name): QObject.__init__(self) search_option = len(sys.argv) >= 2 and sys.argv[1] == "--search" iface = QDBusInterface(dbus_name, object_name, '', QDBusConnection.sessionBus()) if iface.isValid(): iface.call("unique") if search_option: iface.call("search") sys.exit(1) QDBusConnection.sessionBus().registerService(dbus_name) QDBusConnection.sessionBus().registerObject(object_name, self, QDBusConnection.ExportAllSlots)
class DBusThumbnailCache: def __init__(self, bus): self.cache = QDBusInterface( 'org.freedesktop.thumbnails.Cache1', '/org/freedesktop/thumbnails/Cache1', 'org.freedesktop.thumbnails.Cache1', bus) 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 delete(self, files): urls = [url_from_path(f) for f in files] self._call("Delete", dbus_as(urls)) def cleanup(self, files, mtime_threshold=0): urls = ["file://" + urllib.parse.quote(os.path.abspath(f)) for f in files] self._call("Cleanup", dbus_as(urls), mtime_threshold) def copy(self, from_files, to_files): from_uris = [url_from_path(f) for f in from_files] to_uris = [url_from_path(f) for f in to_files] self._call("Copy", dbus_as(from_uris), dbus_as(to_uris)) def move(self, from_files, to_files): from_uris = [url_from_path(f) for f in from_files] to_uris = [url_from_path(f) for f in to_files] self._call("Move", dbus_as(from_uris), dbus_as(to_uris))
def disable_zone(self): try: iface = QDBusInterface("com.deepin.daemon.Zone", "/com/deepin/daemon/Zone", '', QDBusConnection.sessionBus()) iface.asyncCall("EnableZoneDetected", False) except: pass
class Notifier(QObject): _conn = None _interface = None _notifications = None # a dict of notifyId: taskDict _completedTasksStat = None def __init__(self, parent): super().__init__(parent) self._conn = QDBusConnection("Xware Desktop").sessionBus() self._interface = QDBusInterface(_DBUS_NOTIFY_SERVICE, _DBUS_NOTIFY_PATH, _DBUS_NOTIFY_INTERFACE, self._conn) self._notifications = {} self._completedTasksStat = app.etmpy.completedTasksStat self._completedTasksStat.sigTaskCompleted.connect(self.notifyTask) successful = self._conn.connect(_DBUS_NOTIFY_SERVICE, _DBUS_NOTIFY_PATH, _DBUS_NOTIFY_INTERFACE, "ActionInvoked", self.slotActionInvoked) if not successful: logging.error("ActionInvoked connect failed.") self._qSound_complete = QSound(":/sound/download-complete.wav", self) @property def isConnected(self): return self._conn.isConnected() def notifyTask(self, taskId): task = self._completedTasksStat.getTask(taskId) if task.get("state", None) == 11: # see definitions in class TaskStatistic. if app.settings.getbool("frontend", "notifybysound"): self._qSound_complete.play() self._dbus_notify(task) else: # TODO: Also notify if errors occur pass def _dbus_notify(self, task): if not app.settings.getbool("frontend", "popnotifications"): return qdBusMsg = self._interface.call( "Notify", QDBusArgument("Xware Desktop", QMetaType.QString), # app_name QDBusArgument(0, QMetaType.UInt), # replace_id QDBusArgument("/opt/xware_desktop/frontend/thunder.ico", QMetaType.QString), # app_icon QDBusArgument("下载完成", QMetaType.QString), # summary QDBusArgument(task["name"], QMetaType.QString), # body QDBusArgument(["open", "打开", "openDir", "打开文件夹"], QMetaType.QStringList), # actions, { "category": "transfer.complete", }, # hints QDBusArgument(5000, QMetaType.Int), # timeout ) if qdBusMsg.errorName(): logging.error("DBus, notifyTask {}: {}".format(qdBusMsg.errorName(), qdBusMsg.errorMessage())) else: # add it to the dict self._notifications[qdBusMsg.arguments()[0]] = task @pyqtSlot(QDBusMessage) def slotActionInvoked(self, msg): notifyId, action = msg.arguments() task = self._notifications.get(notifyId, None) if not task: # other applications' notifications return name = task["name"] # filename path = task["path"] # location if action == "open": openPath = os.path.join(path, name) elif action == "openDir": openPath = path else: raise Exception("Unknown action from slotActionInvoked.") nativeOpenPath = app.mountsFaker.convertToNativePath(openPath) qUrl = QUrl.fromLocalFile(nativeOpenPath) QDesktopServices().openUrl(qUrl)
class GetwordDaemon(QtCore.QObject): DBUS_NAME = "com.youdao.backend" DBUS_PATH = "/com/youdao/backend" DBUS_IFACE = "com.youdao.backend" hide = QtCore.pyqtSignal() ocrRecognized = QtCore.pyqtSignal(int, int, str, arguments=['x', 'y', 'text']) strokeRecognized = QtCore.pyqtSignal(int, int, str, arguments=['x', 'y', 'text']) ocrEnableChanged = QtCore.pyqtSignal(bool, arguments=['enabled']) strokeEnableChanged = QtCore.pyqtSignal(bool, arguments=['enabled']) cursorPositionChanged = QtCore.pyqtSignal(int, int, arguments=['x', 'y']) doubleCtrlReleased = QtCore.pyqtSignal() altPressed = QtCore.pyqtSignal() ctrlPressed = QtCore.pyqtSignal() shiftPressed = QtCore.pyqtSignal() altReleased = QtCore.pyqtSignal() ctrlReleased = QtCore.pyqtSignal() shiftReleased = QtCore.pyqtSignal() keyPressed = QtCore.pyqtSignal(str, arguments=["name"]) keyReleased = QtCore.pyqtSignal(str, arguments=["name"]) wheelKeyReleased = QtCore.pyqtSignal() def __init__(self): QtCore.QObject.__init__(self) self.session_bus = QDBusConnection.sessionBus() self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'hide', self.hideSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'ocrRecognized', self.ocrRecognizedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'strokeRecognized', self.strokeRecognizedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'ocrEnableChanged', self.ocrEnableChangedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'strokeEnableChanged', self.strokeEnableChangedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'cursorPositionChanged', self.cursorPositionChangedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'doubleCtrlReleased', self.doubleCtrlReleasedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'altPressed', self.altPressedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'ctrlPressed', self.ctrlPressedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'shiftPressed', self.shiftPressedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'altReleased', self.altReleasedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'ctrlReleased', self.ctrlReleasedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'shiftReleased', self.shiftReleasedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'keyPressed', self.keyPressedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'keyReleased', self.keyReleasedSlot) self.session_bus.connect(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, 'wheelKeyReleased', self.wheelKeyReleasedSlot) self.getword_iface = QDBusInterface(self.DBUS_NAME, self.DBUS_PATH, self.DBUS_IFACE, self.session_bus) # signal slot @QtCore.pyqtSlot() def hideSlot(self): self.hide.emit() @QtCore.pyqtSlot() def doubleCtrlReleasedSlot(self): self.doubleCtrlReleased.emit() @QtCore.pyqtSlot() def altPressedSlot(self): self.altPressed.emit() @QtCore.pyqtSlot() def altReleasedSlot(self): self.altReleased.emit() @QtCore.pyqtSlot() def ctrlPressedSlot(self): self.ctrlPressed.emit() @QtCore.pyqtSlot() def ctrlReleasedSlot(self): self.ctrlReleased.emit() @QtCore.pyqtSlot() def shiftPressedSlot(self): self.shiftPressed.emit() @QtCore.pyqtSlot() def shiftReleasedSlot(self): self.shiftReleased.emit() @QtCore.pyqtSlot(str) def keyPressedSlot(self, name): self.keyPressed.emit(name) @QtCore.pyqtSlot(str) def keyReleasedSlot(self, name): self.keyReleased.emit(name) @QtCore.pyqtSlot() def wheelKeyReleasedSlot(self): self.wheelKeyReleased.emit() @QtCore.pyqtSlot(int, int, str) def ocrRecognizedSlot(self, x, y, text): self.ocrRecognized.emit(x, y, text) @QtCore.pyqtSlot(int, int, str) def strokeRecognizedSlot(self, x, y, text): self.strokeRecognized.emit(x, y, text) @QtCore.pyqtSlot(bool) def ocrEnableChangedSlot(self, enable): self.ocrEnableChanged.emit(enable) @QtCore.pyqtSlot(bool) def strokeEnableChangedSlot(self, enable): self.strokeEnableChanged.emit(enable) @QtCore.pyqtSlot(int, int) def cursorPositionChangedSlot(self, x, y): self.cursorPositionChanged.emit(x, y) # method wrap @QtCore.pyqtSlot(str) def PlaySound(self, url): self.getword_iface.call("PlaySound", url) @QtCore.pyqtSlot() def StopSound(self): self.getword_iface.call("StopSound") @QtCore.pyqtSlot() def ClearStroke(self): self.getword_iface.call("ClearStroke") @QtCore.pyqtSlot(bool) def SetOcrEnable(self, value): self.getword_iface.call("SetOcrEnable", value) @QtCore.pyqtSlot(result=bool) def GetOcrEnable(self): return self.getword_iface.call("GetOcrEnable").arguments()[0] @QtCore.pyqtSlot(bool) def SetStrokeEnable(self, value): self.getword_iface.call("SetStrokeEnable", value) @QtCore.pyqtSlot(result=bool) def GetStrokeEnable(self): return self.getword_iface.call("GetStrokeEnable").arguments()[0] @QtCore.pyqtSlot(int, int) def EmitOcr(self, x, y): self.getword_iface.call("EmitOcr", x, y) @QtCore.pyqtSlot() def Quit(self): self.getword_iface.call("Quit")
class DBusThumbnailer(QObject): def __init__(self, bus, listener=None): super().__init__() self.bus = bus self.bus.registerObject('/', self) self.requests: Dict[str, Tuple[str, str, str]] = {} self.thumbnailer = QDBusInterface( 'org.freedesktop.thumbnails.Thumbnailer1', '/org/freedesktop/thumbnails/Thumbnailer1', 'org.freedesktop.thumbnails.Thumbnailer1', connection=self.bus) self.listener = listener self.bus.connect('', '', 'org.freedesktop.thumbnails.Thumbnailer1', 'Ready', self._receive_ready) self.bus.connect('', '', 'org.freedesktop.thumbnails.Thumbnailer1', 'Started', self._receive_started) self.bus.connect('', '', 'org.freedesktop.thumbnails.Thumbnailer1', 'Finished', self._receive_finished) self.bus.connect('', '', 'org.freedesktop.thumbnails.Thumbnailer1', 'Error', self._receive_error) def close(self): self.bus.unregisterObject('/') def _add_request(self, handle, data): self.requests[handle] = data def _remove_request(self, handle): if handle in self.requests: del self.requests[handle] if not self.requests: self.listener.idle() @pyqtSlot(QDBusMessage) def _receive_started(self, msg): handle, = msg.arguments() self.listener.started(handle) @pyqtSlot(QDBusMessage) def _receive_ready(self, msg): handle, uris = msg.arguments() data = self.requests[handle] self.listener.ready(handle, uris, data[2]) @pyqtSlot(QDBusMessage) def _receive_finished(self, msg): handle, = msg.arguments() self.listener.finished(handle) self._remove_request(handle) @pyqtSlot(QDBusMessage) def _receive_error(self, msg): handle, failed_uris, error_code, message = msg.arguments() self.listener.error(handle, failed_uris, error_code, message) def _call(self, method, *args): msg = self.thumbnailer.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 queue(self, files, flavor="default") -> Optional[int]: logger.debug("DBusThumbnailer.queue: %s %s", files, flavor) if files == []: return None urls = ["file://" + urllib.parse.quote(os.path.abspath(f)) for f in files] mime_types = [ mimetypes.guess_type(url)[0] or "application/octet-stream" for url in urls ] handle, = self._call( "Queue", dbus_as(urls), # uris: as dbus_as(mime_types), # mime_types: as flavor, # flavor: s "foreground", # scheduler: s dbus_uint(0), # handle_to_dequeue: u # <arg type="u" name="handle" direction="out" /> ) self._add_request(handle, (urls, mime_types, flavor)) return cast(int, handle) def dequeue(self, handle): logger.debug("DBusThumbnailer.dequeue: %s", handle) handle, = self._call("Dequeue", handle) del self.requests[handle] def get_supported(self): uri_schemes, mime_types = self._call("GetSupported") return (uri_schemes, mime_types) def get_schedulers(self): schedulers, = self._call("GetSchedulers") return schedulers def get_flavors(self): flavors, = self._call("GetFlavors") return flavors @staticmethod def thumbnail_from_filename(filename, flavor="normal"): url = "file://" + urllib.parse.quote(os.path.abspath(filename)) digest = hashlib.md5(os.fsencode(url)).hexdigest() result = os.path.join(xdg.BaseDirectory.xdg_cache_home, "thumbnails", flavor, digest + ".png") return result @staticmethod def thumbnail_from_url(url, flavor="normal"): digest = hashlib.md5(os.fsencode(url)).hexdigest() result = os.path.join(xdg.BaseDirectory.xdg_cache_home, "thumbnails", flavor, digest + ".png") return result
import sys 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 __init__(self, bus): self.cache = QDBusInterface( 'org.freedesktop.thumbnails.Cache1', '/org/freedesktop/thumbnails/Cache1', 'org.freedesktop.thumbnails.Cache1', bus)
class Notifier(QObject): def __init__(self, parent): super().__init__(parent) self._conn = QDBusConnection("Xware Desktop").sessionBus() self._interface = QDBusInterface(_DBUS_NOTIFY_SERVICE, _DBUS_NOTIFY_PATH, _DBUS_NOTIFY_INTERFACE, self._conn) self._notified = {} # a dict of notifyId: taskDict app.taskModel.taskCompleted.connect(self.notifyTaskCompleted, Qt.DirectConnection) self._capabilities = self._getCapabilities() if "actions" in self._capabilities: successful = self._conn.connect(_DBUS_NOTIFY_SERVICE, _DBUS_NOTIFY_PATH, _DBUS_NOTIFY_INTERFACE, "ActionInvoked", self.slotActionInvoked) if not successful: logging.error("ActionInvoked connect failed.") self._qSound_complete = QSound(":/sound/download-complete.wav", self) @property def isConnected(self): return self._conn.isConnected() @pyqtSlot("QObject", result = "void") def notifyTaskCompleted(self, taskItem): if app.settings.getbool("frontend", "notifybysound"): self._qSound_complete.play() if not app.settings.getbool("frontend", "popnotifications"): return self._dbus_notifyCompleted(taskItem) def _getCapabilities(self): # get libnotify server caps and remember it. qdBusMsg = self._interface.call( "GetCapabilities" ) if qdBusMsg.errorName(): logging.error("cannot get org.freedesktop.Notifications.GetCapabilities") return [] else: return qdBusMsg.arguments()[0] def _dbus_notifyCompleted(self, task: "TaskItem"): if "actions" in self._capabilities: actions = QDBusArgument(["open", "打开", "viewOneFile", "在文件夹中显示"], QMetaType.QStringList) else: actions = QDBusArgument([], QMetaType.QStringList) qdBusMsg = self._interface.call( "Notify", QDBusArgument("Xware Desktop", QMetaType.QString), # app_name QDBusArgument(0, QMetaType.UInt), # replace_id QDBusArgument("xware-desktop", QMetaType.QString), # app_icon QDBusArgument("下载完成", QMetaType.QString), # summary QDBusArgument(task.name, QMetaType.QString), # body actions, { "category": "transfer.complete", }, # hints QDBusArgument(5000, QMetaType.Int), # timeout ) if qdBusMsg.errorName(): logging.error("DBus, notifyTask {}: {}".format(qdBusMsg.errorName(), qdBusMsg.errorMessage())) else: # add it to the dict notificationId = qdBusMsg.arguments()[0] self._notified[notificationId] = task.id @pyqtSlot(QDBusMessage) def slotActionInvoked(self, msg): notifyId, action = msg.arguments() taskId = self._notified.get(notifyId, None) if not taskId: # other applications' notifications return taskItem = app.taskModel.taskManager.get(taskId, None) if not taskItem: logging.debug("taskItem cannot be found anymore in TaskModel.") return fullpath = taskItem.fullpath # path + name if action == "open": return systemOpen(fullpath) elif action == "viewOneFile": return viewOneFile(fullpath) elif action == "default": # Unity's notify osd always have a default action. return else: raise Exception("Unknown action from slotActionInvoked: {}.".format(action))