| 83 | |
| 84 | |
| 85 | class FFIEventTracker: |
| 86 | account: Account |
| 87 | _event_queue: Queue |
| 88 | |
| 89 | def __init__(self, account: Account, timeout=None) -> None: |
| 90 | self.account = account |
| 91 | self._timeout = timeout |
| 92 | self._event_queue = Queue() |
| 93 | |
| 94 | @account_hookimpl |
| 95 | def ac_process_ffi_event(self, ffi_event: FFIEvent): |
| 96 | self._event_queue.put(ffi_event) |
| 97 | |
| 98 | def set_timeout(self, timeout): |
| 99 | self._timeout = timeout |
| 100 | |
| 101 | def consume_events(self, check_error=True): |
| 102 | while not self._event_queue.empty(): |
| 103 | self.get(check_error=check_error) |
| 104 | |
| 105 | def get(self, timeout=None, check_error=True): |
| 106 | timeout = timeout if timeout is not None else self._timeout |
| 107 | ev = self._event_queue.get(timeout=timeout) |
| 108 | if check_error and ev.name == "DC_EVENT_ERROR": |
| 109 | raise ValueError(f"unexpected event: {ev}") |
| 110 | return ev |
| 111 | |
| 112 | def iter_events(self, timeout=None, check_error=True): |
| 113 | while True: |
| 114 | yield self.get(timeout=timeout, check_error=check_error) |
| 115 | |
| 116 | def get_matching(self, event_name_regex, check_error=True, timeout=None): |
| 117 | rex = re.compile(f"^(?:{event_name_regex})$") |
| 118 | for ev in self.iter_events(timeout=timeout, check_error=check_error): |
| 119 | if rex.match(ev.name): |
| 120 | return ev |
| 121 | |
| 122 | def get_info_contains(self, regex: str) -> FFIEvent: |
| 123 | rex = re.compile(regex) |
| 124 | while True: |
| 125 | ev = self.get_matching("DC_EVENT_INFO") |
| 126 | if rex.search(ev.data2): |
| 127 | return ev |
| 128 | |
| 129 | def get_info_regex_groups(self, regex, check_error=True): |
| 130 | rex = re.compile(regex) |
| 131 | while True: |
| 132 | ev = self.get_matching("DC_EVENT_INFO", check_error=check_error) |
| 133 | m = rex.match(ev.data2) |
| 134 | if m is not None: |
| 135 | return m.groups() |
| 136 | |
| 137 | def wait_for_connectivity(self, connectivity): |
| 138 | """Wait for the specified connectivity. |
| 139 | This only works reliably if the connectivity doesn't change |
| 140 | again too quickly, otherwise we might miss it. |
| 141 | """ |
| 142 | while True: |