def test_object_method_call(dbus_service): """ Register and call methods on a dbus object. """ def str_response(body=''): return 's', (body, ) interface = 'com.example.interface1' add0 = DBusAddress('/path', dbus_service.name) add1 = DBusAddress('/path/subpath', dbus_service.name) add2 = DBusAddress('/path', dbus_service.name, interface=interface) add3 = DBusAddress('/path/subpath', dbus_service.name, interface=interface) hello0 = partial(str_response, body='Hello0') hello1 = partial(str_response, body='Hello1') hello2 = partial(str_response, body='Hello2') hello3 = partial(str_response, body='Hello3') dbus_service.set_handler(add0.object_path, 'hello0', hello0) dbus_service.set_handler(add1.object_path, 'hello1', hello1) dbus_service.set_handler(add2.object_path, 'hello2', hello2, interface) dbus_service.set_handler(add3.object_path, 'hello3', hello3, interface) dbus_service.listen() conn = connect_and_authenticate() response = conn.send_and_get_reply(new_method_call(add0, 'hello0')) assert response == ('Hello0', ) response = conn.send_and_get_reply(new_method_call(add1, 'hello1')) assert response == ('Hello1', ) response = conn.send_and_get_reply(new_method_call(add2, 'hello2')) assert response == ('Hello2', ) response = conn.send_and_get_reply(new_method_call(add3, 'hello3')) assert response == ('Hello3', )
def dbus_init() -> DBusConnection: """Returns a new connection to the session bus, instance of jeepney's :class:`DBusConnection` class. This connection can then be passed to various SecretStorage functions, such as :func:`~secretstorage.collection.get_default_collection`. It can be used as conext manager that closes the D-Bus socket automatically on exit. Example of usage: .. code-block:: python with secretstorage.dbus_init() as conn: collection = secretstorage.get_default_collection(conn) items = collection.search_items({'application': 'myapp'}) .. versionchanged:: 3.0 Before the port to Jeepney, this function returned an instance of :class:`dbus.SessionBus` class. .. versionchanged:: 3.1 This function no longer accepts any arguments. """ try: connection = connect_and_authenticate() add_match_rules(connection) return ClosingDBusConnectionWrapper(connection) except KeyError as ex: # os.environ['DBUS_SESSION_BUS_ADDRESS'] may raise it reason = "Environment variable {} is unset".format(ex.args[0]) raise SecretServiceNotAvailableException(reason) from ex except (ConnectionError, ValueError) as ex: raise SecretServiceNotAvailableException(str(ex)) from ex
def _get_available_implementation(): macos_version, *_ = platform.mac_ver() if platform.system() == 'Darwin': if IS_MACOS_BUNDLE and Version(macos_version) >= Version( '10.14.0'): # UNUserNotificationCenter is only supported from signed app bundles return SupportedImplementations.notification_center elif Version(macos_version) < Version('10.16.0'): # deprecated but still works return SupportedImplementations.legacy_notification_center elif shutil.which('osascript'): # fallback return SupportedImplementations.osascript elif platform.system() == 'Linux': try: connection = connect_and_authenticate(bus='SESSION') proxy = Proxy(FreedesktopNotifications(), connection) notification_server_info = proxy.GetServerInformation() connection.close() except Exception: notification_server_info = None if notification_server_info: return SupportedImplementations.freedesktop_dbus elif shutil.which('notify-send'): return SupportedImplementations.notify_send return SupportedImplementations.stdout
def get_info_mpris2(name): """ Get the current playing song from an mpris2 compliant player. """ # qdbus org.mpris.MediaPlayer2.<name> /org/mpris/MediaPlayer2\ # org.freedesktop.DBus.Properties.Get org.mpris.MediaPlayer2.Player Metadat bus_name = 'org.mpris.MediaPlayer2.' + name path = '/org/mpris/MediaPlayer2' interface = 'org.mpris.MediaPlayer2.Player' address = DBusAddress(path, bus_name=bus_name, interface=interface) msg = Properties(address).get('Metadata') connection = connect_and_authenticate() response = connection.send_and_get_reply(msg) metadata = dict(response[0][1]) keys = ['album', 'title', 'artist', 'albumartist'] info = {} metadata = {k: v for k, v in metadata.items() if 'xesam:' in k} for key, value in metadata.items(): name = key.split(':')[1].lower() value = value[1] if name not in keys or name in info: continue if isinstance(value, list): value = value[0] info[name] = value if 'albumartist' in info: info['artist'] = info['albumartist'] del info['albumartist'] return Song(**info)
def dbus_init() -> DBusConnection: """Returns a new connection to the session bus, instance of jeepney's :class:`DBusConnection` class. This connection can then be passed to various SecretStorage functions, such as :func:`~secretstorage.collection.get_default_collection`. .. warning:: If you use this function directly, it may result in resource leak as the D-Bus socket will not be closed automatically. We recommend to use :class:`create_connection` context manager instead, which will close the socket on exit. .. versionchanged:: 3.0 Before the port to Jeepney, this function returned an instance of :class:`dbus.SessionBus` class. .. versionchanged:: 3.1 This function no longer accepts any arguments. """ try: connection = connect_and_authenticate() add_match_rules(connection) return connection except KeyError as ex: # os.environ['DBUS_SESSION_BUS_ADDRESS'] may raise it reason = "Environment variable {} is unset".format(ex.args[0]) raise SecretServiceNotAvailableException(reason) from ex except (ConnectionError, ValueError) as ex: raise SecretServiceNotAvailableException(str(ex)) from ex
def dbus_get_metadata(path, bus_name, interface=None): address = DBusAddress(path, bus_name, interface) conn = connect_and_authenticate() metadata = conn.send_and_get_reply(new_method_call(address, 'GetMetadata')) metadata = dict(metadata[0]) keys = ['artist', 'title', 'album'] metadata = {k: v[1] for k, v in metadata.items() if k in keys} return Song(**metadata)
def generate(path, name, output_file, bus='SESSION'): conn = connect_and_authenticate(bus) msg = Introspectable(path, name).Introspect() xml = conn.send_and_get_reply(msg)[0] # print(xml) n_interfaces = code_from_xml(xml, path, name, output_file) print("Written {} interface wrappers to {}".format(n_interfaces, output_file))
def test_basic_init(dbus_service): """ Check that we can successfully initialize and register an object. """ assert dbus_service conn = connect_and_authenticate() msg = DBus().NameHasOwner(dbus_service.name) response = conn.send_and_get_reply(msg) assert response == (1,)
def __init__(self, **kwargs) -> None: super().__init__(**kwargs) address = DBusAddress( "/org/gnome/Mutter/IdleMonitor/Core", bus_name="org.gnome.Mutter.IdleMonitor", interface="org.gnome.Mutter.IdleMonitor", ) self.connection = connect_and_authenticate(bus="SESSION") self.message = new_method_call(address, "GetIdletime")
def test_object_wrong_method_call(dbus_service): """ Try to call an inexistent method and verify that an error is returned. """ object_path = 'com.example.object' addr = DBusAddress('/path', object_path) dbus_service.listen() conn = connect_and_authenticate() with pytest.raises(DBusErrorResponse): conn.send_and_get_reply(new_method_call(addr, 'some_method'))
def test_object_wrong_property(dbus_service): """ Try to get an inexistent property and verify that an error is returned. """ interface = 'com.example.interface1' addr = DBusAddress('/path', dbus_service.name, interface=interface) dbus_service.listen() conn = connect_and_authenticate() with pytest.raises(DBusErrorResponse): conn.send_and_get_reply(Properties(addr).get('prop'))
def _grab_to_file(self, filename, bbox=None): has_jeepney = False try: from jeepney.wrappers import MessageGenerator, new_method_call from jeepney import new_method_call from jeepney.integrate.blocking import connect_and_authenticate has_jeepney = True except ImportError: pass if not has_jeepney: raise GnomeDBusError("jeepney library is missing") class Screenshot(MessageGenerator): interface = "org.gnome.Shell.Screenshot" def __init__( self, object_path="/org/gnome/Shell/Screenshot", bus_name="org.gnome.Shell.Screenshot", ): super().__init__(object_path=object_path, bus_name=bus_name) def Screenshot(self, include_cursor, flash, filename): return new_method_call(self, "Screenshot", "bbs", (include_cursor, flash, filename)) def ScreenshotArea(self, x, y, width, height, flash, filename): return new_method_call( self, "ScreenshotArea", "iiiibs", (x, y, width, height, flash, filename), ) # https://jeepney.readthedocs.io/en/latest/integrate.html connection = connect_and_authenticate(bus="SESSION") dbscr = Screenshot() if bbox: msg = dbscr.ScreenshotArea( bbox[0], bbox[1], bbox[2] - bbox[0], bbox[3] - bbox[1], False, filename, ) else: msg = dbscr.Screenshot(False, False, filename) result = connection.send_and_get_reply(msg) if not result[0]: raise GnomeDBusError("dbus error: %s %s" % (msg, result))
def test_object_wrong_method_call(dbus_service): """ Try to call an inexistent method and verify that an error is returned. """ addr = DBusAddress('/path', dbus_service.name) dbus_service.listen() conn = connect_and_authenticate() with pytest.raises(DBusErrorResponse) as err: conn.send_and_get_reply(new_method_call(addr, 'some_method')) assert err.value.name == 'com.example.object.exceptions.KeyError' assert err.value.data == ("Unregistered method: 'some_method'",)
def grab(self, bbox=None): has_jeepney = False try: from jeepney.wrappers import MessageGenerator, new_method_call from jeepney import new_method_call from jeepney.integrate.blocking import connect_and_authenticate has_jeepney = True except ImportError: pass if not has_jeepney: raise KdeDBusError("jeepney library is missing") class Screenshot(MessageGenerator): interface = "org.kde.kwin.Screenshot" def __init__(self, object_path="/Screenshot", bus_name="org.kde.KWin"): super().__init__(object_path=object_path, bus_name=bus_name) def screenshotFullscreen(self, captureCursor): return new_method_call(self, "screenshotFullscreen", "b", (captureCursor, )) def screenshotArea(self, x, y, width, height, captureCursor): return new_method_call( self, "screenshotArea", "iiiib", (x, y, width, height, captureCursor), ) # https://jeepney.readthedocs.io/en/latest/integrate.html connection = connect_and_authenticate(bus="SESSION") dbscr = Screenshot() # bbox not working: # if bbox: msg = dbscr.screenshotArea(bbox[0], bbox[1], bbox[2] - bbox[0], bbox[3] - bbox[1], False) msg = dbscr.screenshotFullscreen(False) filename = connection.send_and_get_reply(msg) filename = filename[0] if not filename: raise KdeDBusError() im = Image.open(filename) os.remove(filename) if bbox: im = im.crop(bbox) return im
def test_object_method_call_args(dbus_service): """ Set a method handler that can take arguments and verify that we can call it. """ def mirror(arg): return ('s', (arg,)) path = '/path' dbus_service.set_handler(path, 'ping', mirror) dbus_service.listen() addr = DBusAddress('/path', dbus_service.name) conn = connect_and_authenticate() response = conn.send_and_get_reply( new_method_call(addr, 'ping', 's', ('Repeat after me',)) ) assert response == ('Repeat after me',)
def suspend_with_dbus(): suspend = DBusAddress('/org/freedesktop/login1', bus_name='org.freedesktop.login1', interface='org.freedesktop.login1.Manager') connection = connect_and_authenticate(bus='SYSTEM') # Construct a new D-Bus message. new_method_call takes the address, the # method name, the signature string, and a tuple of arguments. # 'signature string' is not documented well, it's bascally the argument types. More info here # https://dbus.freedesktop.org/doc/dbus-specification.html#type-system msg = new_method_call(suspend, 'Suspend', 'b', (True, )) # Send the message and wait for the reply reply = connection.send_and_get_reply(msg) print('Reply: ', reply) connection.close()
def test_object_get_property(dbus_service): """ Set and get properties from a dbus object. """ interface = 'com.example.interface1' add0 = DBusAddress('/path', dbus_service.name, interface=interface) add1 = DBusAddress('/path/subpath', dbus_service.name, interface=interface) dbus_service.set_property(add0.object_path, 'prop0', 's', ('hello0',), add0.interface) dbus_service.set_property(add1.object_path, 'prop1', 's', ('hello1',), add1.interface) dbus_service.listen() conn = connect_and_authenticate() response = conn.send_and_get_reply(Properties(add0).get('prop0')) assert response == ('hello0', ) response = conn.send_and_get_reply(Properties(add1).get('prop1')) assert response == ('hello1', )
def test_object_get_all_properties(dbus_service): """ Get all properties from a dbus object. """ interface = 'com.example.interface1' addr = DBusAddress('/path', dbus_service.name, interface=interface) dbus_service.set_property(addr.object_path, 'prop0', 's', 'hello0', addr.interface) dbus_service.set_property(addr.object_path, 'prop1', 's', 'hello1', addr.interface) dbus_service.set_property(addr.object_path, 'prop2', 's', 'hello2', addr.interface) dbus_service.listen() conn = connect_and_authenticate() response = conn.send_and_get_reply(Properties(addr).get_all()) assert response == ([('prop0', ('s', 'hello0')), ('prop1', ('s', 'hello1')), ('prop2', ('s', 'hello2'))], )
def gps_to_dbus(dbusargs): if len(dbusargs) != 15: print( 'tuple argument for gps_to_dbus was not valid. Expected 15 entries, got', len(dbusargs)) return -1 gps = DBusAddress('/org/gpsd', bus_name=None, interface='org.gpsd') connection = connect_and_authenticate(bus='SYSTEM') # Construct a new D-Bus message. new_method_call takes the address, the # method name, the signature string, and a tuple of arguments. # 'signature string' is not documented well, it's basically the argument types. More info here # https://dbus.freedesktop.org/doc/dbus-specification.html#type-system msg = new_signal(gps, 'fix', 'didddddddddddds', dbusargs) # Send the message and wait for the reply reply = connection.send_message(msg) #print('Reply: ', reply) connection.close()
def test_object_set_readonly_property(dbus_service): """ Try to set the value for a readonly property and check that a permissions error is returned. """ name = 'someprop' value = ('somevalue',) path = '/' interface = 'some.interface' prop = DBusProperty(name, 's', value, access='read') dbus_service.interfaces[(path, interface)].properties[name] = prop dbus_service.listen() conn = connect_and_authenticate() addr = DBusAddress(path, dbus_service.name, interface) msg = Properties(addr).set(name, 's', 'anothervalue') with pytest.raises(DBusErrorResponse) as err: conn.send_and_get_reply(msg) assert err.value.name == 'com.example.object.exceptions.PermissionError' assert err.value.data == (f'{name}: Property not settable',) # check that the original property hasn't changed assert prop.value == value
def dbus_init() -> DBusConnection: """Returns a new connection to the session bus, instance of jeepney's :class:`DBusConnection` class. This connection can then be passed to various SecretStorage functions, such as :func:`~secretstorage.collection.get_default_collection`. .. warning:: The D-Bus socket will not be closed automatically. You can close it manually using the :meth:`DBusConnection.close` method, or you can use the :class:`contextlib.closing` context manager: .. code-block:: python from contextlib import closing with closing(dbus_init()) as conn: collection = secretstorage.get_default_collection(conn) items = collection.search_items({'application': 'myapp'}) However, you will not be able to call any methods on the objects created within the context after you leave it. .. versionchanged:: 3.0 Before the port to Jeepney, this function returned an instance of :class:`dbus.SessionBus` class. .. versionchanged:: 3.1 This function no longer accepts any arguments. """ try: connection = connect_and_authenticate() add_match_rules(connection) return connection except KeyError as ex: # os.environ['DBUS_SESSION_BUS_ADDRESS'] may raise it reason = "Environment variable {} is unset".format(ex.args[0]) raise SecretServiceNotAvailableException(reason) from ex except (ConnectionError, ValueError) as ex: raise SecretServiceNotAvailableException(str(ex)) from ex
def dbus_init() -> DBusConnection: """Returns a new connection to the session bus, instance of :class:`jeepney.DBusConnection` instance. This connection can then be passed to various SecretStorage functions, such as :func:`~secretstorage.collection.get_default_collection`. .. versionchanged:: 3.0 Before the port to Jeepney, this function returned an instance of :class:`dbus.SessionBus` class. .. versionchanged:: 3.1 This function no longer accepts any arguments. """ try: connection = connect_and_authenticate() add_match_rules(connection) return connection except KeyError as ex: # os.environ['DBUS_SESSION_BUS_ADDRESS'] may raise it reason = "Environment variable {} is unset".format(ex.args[0]) raise SecretServiceNotAvailableException(reason) from ex except (ConnectionError, ValueError) as ex: raise SecretServiceNotAvailableException(str(ex)) from ex
def run(self): items = [] visited = set() try: import dbus import secretstorage import datetime except ImportError as e: self.error('libsecret: {0}'.format(e)) return [] for uid, session in homes.sessions(): try: # List bus connection names bus = dbus.bus.BusConnection(session) if 'org.freedesktop.secrets' not in [ str(x) for x in bus.list_names() ]: continue except Exception: self.error(traceback.format_exc()) continue collections = None try: # Python 2.7 collections = list( secretstorage.collection.get_all_collections(bus)) except Exception: pass if not collections: try: # Python 3 from jeepney.integrate.blocking import connect_and_authenticate make_auth_external.uid = uid bus = connect_and_authenticate(session) collections = secretstorage.get_all_collections(bus) except Exception: self.error(traceback.format_exc()) continue for collection in collections: if collection.is_locked(): continue label = collection.get_label() if label in visited: continue visited.add(label) try: storage = collection.get_all_items() except Exception: self.error(traceback.format_exc()) continue for item in storage: values = { 'created': str(datetime.datetime.fromtimestamp( item.get_created())), 'modified': str( datetime.datetime.fromtimestamp( item.get_modified())), 'content-type': item.get_secret_content_type(), 'label': item.get_label(), 'Password': item.get_secret().decode('utf8'), 'collection': label, } # for k, v in item.get_attributes().iteritems(): # values[unicode(k)] = unicode(v) items.append(values) try: bus.flush() bus.close() except Exception: pass return items
#!/usr/bin/python3 from jeepney.integrate.blocking import connect_and_authenticate from jukebox.tracklist import Queue from jukebox.search import YouTubeFinder with connect_and_authenticate(bus="SESSION") as connection: finder = YouTubeFinder() queue = Queue(connection) try: while True: query = input("ytsearch: ") if len(query) > 0: result = finder.search(query) queue.addTrack(result) except EOFError: pass except KeyboardInterrupt: pass
def __init__(self, app_name): super().__init__(app_name) connection = connect_and_authenticate(bus='SESSION') self.proxy = Proxy(FreedesktopNotifications(), connection) self._past_notification_ids = deque([0] * self.notification_limit)
def __init__(self): self.name = None self.interfaces = defaultdict(DBusInterface) self.conn = connect_and_authenticate(bus='SESSION') self.conn.router.on_unhandled = self.handle_msg self.listen_process = None
def run(self): items = [] visited = set() try: import dbus import secretstorage import datetime except ImportError as e: self.error('libsecret: {0}'.format(e)) return [] for uid, session in homes.sessions(): try: # List bus connection names bus = dbus.bus.BusConnection(session) if 'org.freedesktop.secrets' not in [str(x) for x in bus.list_names()]: continue except Exception: self.error(traceback.format_exc()) continue collections = None try: # Python 2.7 collections = list(secretstorage.collection.get_all_collections(bus)) except Exception: pass if not collections: try: # Python 3 from jeepney.integrate.blocking import connect_and_authenticate make_auth_external.uid = uid bus = connect_and_authenticate(session) collections = secretstorage.get_all_collections(bus) except Exception: self.error(traceback.format_exc()) continue for collection in collections: if collection.is_locked(): continue label = collection.get_label() if label in visited: continue visited.add(label) try: storage = collection.get_all_items() except Exception: self.error(traceback.format_exc()) continue for item in storage: values = { 'created': str(datetime.datetime.fromtimestamp(item.get_created())), 'modified': str(datetime.datetime.fromtimestamp(item.get_modified())), 'content-type': item.get_secret_content_type(), 'label': item.get_label(), 'Password': item.get_secret().decode('utf8'), 'collection': label, } # for k, v in item.get_attributes().iteritems(): # values[unicode(k)] = unicode(v) items.append(values) try: bus.flush() bus.close() except Exception: pass return items