Exemple #1
0
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', )
Exemple #2
0
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
Exemple #3
0
    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
Exemple #4
0
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)
Exemple #5
0
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
Exemple #6
0
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)
Exemple #7
0
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))
Exemple #8
0
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,)
Exemple #9
0
    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")
Exemple #10
0
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'))
Exemple #11
0
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'))
Exemple #12
0
    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))
Exemple #13
0
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
Exemple #15
0
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',)
Exemple #16
0
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()
Exemple #17
0
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', )
Exemple #18
0
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'))], )
Exemple #19
0
    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()
Exemple #20
0
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
Exemple #22
0
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
Exemple #23
0
    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
Exemple #24
0
#!/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

Exemple #25
0
 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)
Exemple #26
0
 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
Exemple #27
0
    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