File: __init__.py

package info (click to toggle)
libei 1.5.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 1,916 kB
  • sloc: ansic: 23,868; python: 2,712; xml: 1,243; sh: 142; makefile: 63; cpp: 12; lisp: 2
file content (124 lines) | stat: -rw-r--r-- 3,773 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# SPDX-License-Identifier: MIT
#
#
# This file is formatted with Python Black

from dbusmock import DBusMockObject
from typing import Dict, Any, NamedTuple, Optional
from itertools import count
from gi.repository import GLib  # type: ignore

import dbus
import dbus.service
import logging


ASVType = Dict[str, Any]

logging.basicConfig(format="%(levelname).1s|%(name)s: %(message)s", level=logging.DEBUG)
logger = logging.getLogger("templates")


class MockParams:
    """
    Helper class for storing template parameters. The Mock object passed into
    ``load()`` is shared between all templates. This makes it easy to have
    per-template parameters by calling:

        >>> params = MockParams.get(mock, MAIN_IFACE)
        >>> params.version = 1

    and later, inside a DBus method:
        >>> params = MockParams.get(self, MAIN_IFACE)
        >>> return params.version
    """

    @classmethod
    def get(cls, mock, interface_name):
        params = getattr(mock, "params", {})
        try:
            return params[interface_name]
        except KeyError:
            c = cls()
            params[interface_name] = c
            mock.params = params
            return c


class Response(NamedTuple):
    response: int
    results: ASVType


class Request:
    _token_counter = count()

    def __init__(
        self, bus_name: dbus.service.BusName, sender: str, options: Optional[ASVType]
    ):
        options = options or {}
        sender_token = sender.removeprefix(":").replace(".", "_")
        handle_token = options.get("handle_token", next(self._token_counter))
        self.sender = sender
        self.handle = (
            f"/org/freedesktop/portal/desktop/request/{sender_token}/{handle_token}"
        )
        self.mock = DBusMockObject(
            bus_name=bus_name,
            path=self.handle,
            interface="org.freedesktop.portal.Request",
            props={},
        )
        self.mock.AddMethod("", "Close", "", "", "self.RemoveObject(self.path)")
        logger.debug(f"Request created at {self.handle}")

    def respond(self, response: Response, delay: int = 0):
        def respond():
            logger.debug(f"Request.Response on {self.handle}: {response}")
            self.mock.EmitSignalDetailed(
                "",
                "Response",
                "ua{sv}",
                [dbus.UInt32(response.response), response.results],
                details={"destination": self.sender},
            )

        if delay > 0:
            GLib.timeout_add(delay, respond)
        else:
            respond()


class Session:
    _token_counter = count()

    def __init__(
        self, bus_name: dbus.service.BusName, sender: str, options: Optional[ASVType]
    ):
        options = options or {}
        sender_token = sender.removeprefix(":").replace(".", "_")
        handle_token = options.get("session_handle_token", next(self._token_counter))
        self.sender = sender
        self.handle = (
            f"/org/freedesktop/portal/desktop/session/{sender_token}/{handle_token}"
        )
        self.mock = DBusMockObject(
            bus_name=bus_name,
            path=self.handle,
            interface="org.freedesktop.portal.Session",
            props={},
        )
        self.mock.AddMethod("", "Close", "", "", "self.RemoveObject(self.path)")
        logger.debug(f"Session created at {self.handle}")

    def close(self, details: ASVType, delay: int = 0):
        def respond():
            logger.debug(f"Session.Closed on {self.handle}: {details}")
            self.mock.EmitSignalDetailed(
                "", "Closed", "a{sv}", [details], destination=self.sender
            )

        if delay > 0:
            GLib.timeout_add(delay, respond)
        else:
            respond()