deltachat-rpc-client 1.159.3__tar.gz → 1.159.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {deltachat_rpc_client-1.159.3/src/deltachat_rpc_client.egg-info → deltachat_rpc_client-1.159.5}/PKG-INFO +1 -1
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/pyproject.toml +1 -1
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/__init__.py +1 -1
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/_utils.py +3 -3
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/account.py +24 -11
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/chat.py +6 -3
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/client.py +4 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/const.py +24 -16
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/contact.py +7 -4
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/deltachat.py +6 -5
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/events.py +31 -26
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/message.py +12 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/pytestplugin.py +20 -1
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/rpc.py +22 -7
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5/src/deltachat_rpc_client.egg-info}/PKG-INFO +1 -1
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/LICENSE +0 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/README.md +0 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/setup.cfg +0 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/py.typed +0 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client.egg-info/SOURCES.txt +0 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client.egg-info/dependency_links.txt +0 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client.egg-info/entry_points.txt +0 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client.egg-info/top_level.txt +0 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/tests/test_account_events.py +0 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/tests/test_chatlist_events.py +0 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/tests/test_iroh_webxdc.py +0 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/tests/test_key_transfer.py +0 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/tests/test_multidevice.py +0 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/tests/test_securejoin.py +0 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/tests/test_something.py +0 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/tests/test_vcard.py +0 -0
- {deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/tests/test_webxdc.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "deltachat-rpc-client"
|
|
7
|
-
version = "1.159.
|
|
7
|
+
version = "1.159.5"
|
|
8
8
|
description = "Python client for Delta Chat core JSON-RPC interface"
|
|
9
9
|
classifiers = [
|
|
10
10
|
"Development Status :: 5 - Production/Stable",
|
{deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/_utils.py
RENAMED
|
@@ -115,7 +115,7 @@ def _run_cli(
|
|
|
115
115
|
|
|
116
116
|
|
|
117
117
|
def extract_addr(text: str) -> str:
|
|
118
|
-
"""
|
|
118
|
+
"""Extract email address from the given text."""
|
|
119
119
|
match = re.match(r".*\((.+@.+)\)", text)
|
|
120
120
|
if match:
|
|
121
121
|
text = match.group(1)
|
|
@@ -124,7 +124,7 @@ def extract_addr(text: str) -> str:
|
|
|
124
124
|
|
|
125
125
|
|
|
126
126
|
def parse_system_image_changed(text: str) -> Optional[Tuple[str, bool]]:
|
|
127
|
-
"""
|
|
127
|
+
"""Return image changed/deleted info from parsing the given system message text."""
|
|
128
128
|
text = text.lower()
|
|
129
129
|
match = re.match(r"group image (changed|deleted) by (.+).", text)
|
|
130
130
|
if match:
|
|
@@ -143,7 +143,7 @@ def parse_system_title_changed(text: str) -> Optional[Tuple[str, str]]:
|
|
|
143
143
|
|
|
144
144
|
|
|
145
145
|
def parse_system_add_remove(text: str) -> Optional[Tuple[str, str, str]]:
|
|
146
|
-
"""
|
|
146
|
+
"""Return add/remove info from parsing the given system message text.
|
|
147
147
|
|
|
148
148
|
returns a (action, affected, actor) tuple.
|
|
149
149
|
"""
|
{deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/account.py
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Account module."""
|
|
2
|
+
|
|
1
3
|
from __future__ import annotations
|
|
2
4
|
|
|
3
5
|
from dataclasses import dataclass
|
|
@@ -34,7 +36,10 @@ class Account:
|
|
|
34
36
|
return next_event
|
|
35
37
|
|
|
36
38
|
def clear_all_events(self):
|
|
37
|
-
"""
|
|
39
|
+
"""Remove all queued-up events for a given account.
|
|
40
|
+
|
|
41
|
+
Useful for tests.
|
|
42
|
+
"""
|
|
38
43
|
self._rpc.clear_all_events(self.id)
|
|
39
44
|
|
|
40
45
|
def remove(self) -> None:
|
|
@@ -43,7 +48,9 @@ class Account:
|
|
|
43
48
|
|
|
44
49
|
def clone(self) -> "Account":
|
|
45
50
|
"""Clone given account.
|
|
46
|
-
|
|
51
|
+
|
|
52
|
+
This uses backup-transfer via iroh, i.e. the 'Add second device' feature.
|
|
53
|
+
"""
|
|
47
54
|
future = self._rpc.provide_backup.future(self.id)
|
|
48
55
|
qr = self._rpc.get_backup_qr(self.id)
|
|
49
56
|
new_account = self.manager.add_account()
|
|
@@ -80,7 +87,7 @@ class Account:
|
|
|
80
87
|
return self._rpc.get_config(self.id, key)
|
|
81
88
|
|
|
82
89
|
def update_config(self, **kwargs) -> None:
|
|
83
|
-
"""
|
|
90
|
+
"""Update config values."""
|
|
84
91
|
for key, value in kwargs.items():
|
|
85
92
|
self.set_config(key, value)
|
|
86
93
|
|
|
@@ -99,10 +106,12 @@ class Account:
|
|
|
99
106
|
"""Parse QR code contents.
|
|
100
107
|
|
|
101
108
|
This function takes the raw text scanned
|
|
102
|
-
and checks what can be done with it.
|
|
109
|
+
and checks what can be done with it.
|
|
110
|
+
"""
|
|
103
111
|
return self._rpc.check_qr(self.id, qr)
|
|
104
112
|
|
|
105
113
|
def set_config_from_qr(self, qr: str):
|
|
114
|
+
"""Set configuration values from a QR code."""
|
|
106
115
|
self._rpc.set_config_from_qr(self.id, qr)
|
|
107
116
|
|
|
108
117
|
@futuremethod
|
|
@@ -117,7 +126,7 @@ class Account:
|
|
|
117
126
|
|
|
118
127
|
@futuremethod
|
|
119
128
|
def list_transports(self):
|
|
120
|
-
"""
|
|
129
|
+
"""Return the list of all email accounts that are used as a transport in the current profile."""
|
|
121
130
|
transports = yield self._rpc.list_transports.future(self.id)
|
|
122
131
|
return transports
|
|
123
132
|
|
|
@@ -158,7 +167,8 @@ class Account:
|
|
|
158
167
|
def import_vcard(self, vcard: str) -> list[Contact]:
|
|
159
168
|
"""Import vCard.
|
|
160
169
|
|
|
161
|
-
Return created or modified contacts in the order they appear in vCard.
|
|
170
|
+
Return created or modified contacts in the order they appear in vCard.
|
|
171
|
+
"""
|
|
162
172
|
contact_ids = self._rpc.import_vcard_contents(self.id, vcard)
|
|
163
173
|
return [Contact(self, contact_id) for contact_id in contact_ids]
|
|
164
174
|
|
|
@@ -227,12 +237,12 @@ class Account:
|
|
|
227
237
|
|
|
228
238
|
@property
|
|
229
239
|
def self_contact(self) -> Contact:
|
|
230
|
-
"""
|
|
240
|
+
"""Account's identity as a Contact."""
|
|
231
241
|
return Contact(self, SpecialContactId.SELF)
|
|
232
242
|
|
|
233
243
|
@property
|
|
234
244
|
def device_contact(self) -> Chat:
|
|
235
|
-
"""
|
|
245
|
+
"""Account's device contact."""
|
|
236
246
|
return Contact(self, SpecialContactId.DEVICE)
|
|
237
247
|
|
|
238
248
|
def get_chatlist(
|
|
@@ -290,8 +300,7 @@ class Account:
|
|
|
290
300
|
return Chat(self, chat_id)
|
|
291
301
|
|
|
292
302
|
def secure_join(self, qrdata: str) -> Chat:
|
|
293
|
-
"""Continue a Setup-Contact or Verified-Group-Invite protocol started on
|
|
294
|
-
another device.
|
|
303
|
+
"""Continue a Setup-Contact or Verified-Group-Invite protocol started on another device.
|
|
295
304
|
|
|
296
305
|
The function returns immediately and the handshake runs in background, sending
|
|
297
306
|
and receiving several messages.
|
|
@@ -361,22 +370,26 @@ class Account:
|
|
|
361
370
|
def wait_for_incoming_msg(self):
|
|
362
371
|
"""Wait for incoming message and return it.
|
|
363
372
|
|
|
364
|
-
Consumes all events before the next incoming message event.
|
|
373
|
+
Consumes all events before the next incoming message event.
|
|
374
|
+
"""
|
|
365
375
|
return self.get_message_by_id(self.wait_for_incoming_msg_event().msg_id)
|
|
366
376
|
|
|
367
377
|
def wait_for_securejoin_inviter_success(self):
|
|
378
|
+
"""Wait until SecureJoin process finishes successfully on the inviter side."""
|
|
368
379
|
while True:
|
|
369
380
|
event = self.wait_for_event()
|
|
370
381
|
if event["kind"] == "SecurejoinInviterProgress" and event["progress"] == 1000:
|
|
371
382
|
break
|
|
372
383
|
|
|
373
384
|
def wait_for_securejoin_joiner_success(self):
|
|
385
|
+
"""Wait until SecureJoin process finishes successfully on the joiner side."""
|
|
374
386
|
while True:
|
|
375
387
|
event = self.wait_for_event()
|
|
376
388
|
if event["kind"] == "SecurejoinJoinerProgress" and event["progress"] == 1000:
|
|
377
389
|
break
|
|
378
390
|
|
|
379
391
|
def wait_for_reactions_changed(self):
|
|
392
|
+
"""Wait for reaction change event."""
|
|
380
393
|
return self.wait_for_event(EventType.REACTIONS_CHANGED)
|
|
381
394
|
|
|
382
395
|
def get_fresh_messages_in_arrival_order(self) -> list[Message]:
|
{deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/chat.py
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Chat module."""
|
|
2
|
+
|
|
1
3
|
from __future__ import annotations
|
|
2
4
|
|
|
3
5
|
import calendar
|
|
@@ -89,7 +91,8 @@ class Chat:
|
|
|
89
91
|
def set_ephemeral_timer(self, timer: int) -> None:
|
|
90
92
|
"""Set ephemeral timer of this chat in seconds.
|
|
91
93
|
|
|
92
|
-
0 means the timer is disabled, use 1 for immediate deletion.
|
|
94
|
+
0 means the timer is disabled, use 1 for immediate deletion.
|
|
95
|
+
"""
|
|
93
96
|
self._rpc.set_chat_ephemeral_timer(self.account.id, self.id, timer)
|
|
94
97
|
|
|
95
98
|
def get_encryption_info(self) -> str:
|
|
@@ -199,12 +202,12 @@ class Chat:
|
|
|
199
202
|
return snapshot
|
|
200
203
|
|
|
201
204
|
def get_messages(self, info_only: bool = False, add_daymarker: bool = False) -> list[Message]:
|
|
202
|
-
"""
|
|
205
|
+
"""Get the list of messages in this chat."""
|
|
203
206
|
msgs = self._rpc.get_message_ids(self.account.id, self.id, info_only, add_daymarker)
|
|
204
207
|
return [Message(self.account, msg_id) for msg_id in msgs]
|
|
205
208
|
|
|
206
209
|
def get_fresh_message_count(self) -> int:
|
|
207
|
-
"""Get number of fresh messages in this chat"""
|
|
210
|
+
"""Get number of fresh messages in this chat."""
|
|
208
211
|
return self._rpc.get_fresh_msg_cnt(self.account.id, self.id)
|
|
209
212
|
|
|
210
213
|
def mark_noticed(self) -> None:
|
{deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/client.py
RENAMED
|
@@ -48,6 +48,7 @@ class Client:
|
|
|
48
48
|
self.add_hooks(hooks or [])
|
|
49
49
|
|
|
50
50
|
def add_hooks(self, hooks: Iterable[tuple[Callable, Union[type, EventFilter]]]) -> None:
|
|
51
|
+
"""Register multiple hooks."""
|
|
51
52
|
for hook, event in hooks:
|
|
52
53
|
self.add_hook(hook, event)
|
|
53
54
|
|
|
@@ -77,9 +78,11 @@ class Client:
|
|
|
77
78
|
self._hooks.get(type(event), set()).remove((hook, event))
|
|
78
79
|
|
|
79
80
|
def is_configured(self) -> bool:
|
|
81
|
+
"""Return True if the client is configured."""
|
|
80
82
|
return self.account.is_configured()
|
|
81
83
|
|
|
82
84
|
def configure(self, email: str, password: str, **kwargs) -> None:
|
|
85
|
+
"""Configure the client."""
|
|
83
86
|
self.account.set_config("addr", email)
|
|
84
87
|
self.account.set_config("mail_pw", password)
|
|
85
88
|
for key, value in kwargs.items():
|
|
@@ -198,5 +201,6 @@ class Bot(Client):
|
|
|
198
201
|
"""Simple bot implementation that listens to events of a single account."""
|
|
199
202
|
|
|
200
203
|
def configure(self, email: str, password: str, **kwargs) -> None:
|
|
204
|
+
"""Configure the bot."""
|
|
201
205
|
kwargs.setdefault("bot", "1")
|
|
202
206
|
super().configure(email, password, **kwargs)
|
{deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/const.py
RENAMED
|
@@ -1,14 +1,20 @@
|
|
|
1
|
+
"""Constants module."""
|
|
2
|
+
|
|
1
3
|
from enum import Enum, IntEnum
|
|
2
4
|
|
|
3
5
|
COMMAND_PREFIX = "/"
|
|
4
6
|
|
|
5
7
|
|
|
6
8
|
class ContactFlag(IntEnum):
|
|
9
|
+
"""Bit flags for get_contacts() method."""
|
|
10
|
+
|
|
7
11
|
VERIFIED_ONLY = 0x01
|
|
8
12
|
ADD_SELF = 0x02
|
|
9
13
|
|
|
10
14
|
|
|
11
15
|
class ChatlistFlag(IntEnum):
|
|
16
|
+
"""Bit flags for get_chatlist() method."""
|
|
17
|
+
|
|
12
18
|
ARCHIVED_ONLY = 0x01
|
|
13
19
|
NO_SPECIALS = 0x02
|
|
14
20
|
ADD_ALLDONE_HINT = 0x04
|
|
@@ -16,6 +22,8 @@ class ChatlistFlag(IntEnum):
|
|
|
16
22
|
|
|
17
23
|
|
|
18
24
|
class SpecialContactId(IntEnum):
|
|
25
|
+
"""Special contact IDs."""
|
|
26
|
+
|
|
19
27
|
SELF = 1
|
|
20
28
|
INFO = 2 # centered messages as "member added", used in all chats
|
|
21
29
|
DEVICE = 5 # messages "update info" in the device-chat
|
|
@@ -23,7 +31,7 @@ class SpecialContactId(IntEnum):
|
|
|
23
31
|
|
|
24
32
|
|
|
25
33
|
class EventType(str, Enum):
|
|
26
|
-
"""Core event types"""
|
|
34
|
+
"""Core event types."""
|
|
27
35
|
|
|
28
36
|
INFO = "Info"
|
|
29
37
|
SMTP_CONNECTED = "SmtpConnected"
|
|
@@ -71,7 +79,7 @@ class EventType(str, Enum):
|
|
|
71
79
|
|
|
72
80
|
|
|
73
81
|
class ChatId(IntEnum):
|
|
74
|
-
"""Special chat
|
|
82
|
+
"""Special chat IDs."""
|
|
75
83
|
|
|
76
84
|
TRASH = 3
|
|
77
85
|
ARCHIVED_LINK = 6
|
|
@@ -80,7 +88,7 @@ class ChatId(IntEnum):
|
|
|
80
88
|
|
|
81
89
|
|
|
82
90
|
class ChatType(IntEnum):
|
|
83
|
-
"""Chat
|
|
91
|
+
"""Chat type."""
|
|
84
92
|
|
|
85
93
|
UNDEFINED = 0
|
|
86
94
|
SINGLE = 100
|
|
@@ -90,7 +98,7 @@ class ChatType(IntEnum):
|
|
|
90
98
|
|
|
91
99
|
|
|
92
100
|
class ChatVisibility(str, Enum):
|
|
93
|
-
"""Chat visibility types"""
|
|
101
|
+
"""Chat visibility types."""
|
|
94
102
|
|
|
95
103
|
NORMAL = "Normal"
|
|
96
104
|
ARCHIVED = "Archived"
|
|
@@ -98,7 +106,7 @@ class ChatVisibility(str, Enum):
|
|
|
98
106
|
|
|
99
107
|
|
|
100
108
|
class DownloadState(str, Enum):
|
|
101
|
-
"""Message download state"""
|
|
109
|
+
"""Message download state."""
|
|
102
110
|
|
|
103
111
|
DONE = "Done"
|
|
104
112
|
AVAILABLE = "Available"
|
|
@@ -159,14 +167,14 @@ class MessageState(IntEnum):
|
|
|
159
167
|
|
|
160
168
|
|
|
161
169
|
class MessageId(IntEnum):
|
|
162
|
-
"""Special message
|
|
170
|
+
"""Special message IDs."""
|
|
163
171
|
|
|
164
172
|
DAYMARKER = 9
|
|
165
173
|
LAST_SPECIAL = 9
|
|
166
174
|
|
|
167
175
|
|
|
168
176
|
class CertificateChecks(IntEnum):
|
|
169
|
-
"""Certificate checks mode"""
|
|
177
|
+
"""Certificate checks mode."""
|
|
170
178
|
|
|
171
179
|
AUTOMATIC = 0
|
|
172
180
|
STRICT = 1
|
|
@@ -174,7 +182,7 @@ class CertificateChecks(IntEnum):
|
|
|
174
182
|
|
|
175
183
|
|
|
176
184
|
class Connectivity(IntEnum):
|
|
177
|
-
"""Connectivity states"""
|
|
185
|
+
"""Connectivity states."""
|
|
178
186
|
|
|
179
187
|
NOT_CONNECTED = 1000
|
|
180
188
|
CONNECTING = 2000
|
|
@@ -183,7 +191,7 @@ class Connectivity(IntEnum):
|
|
|
183
191
|
|
|
184
192
|
|
|
185
193
|
class KeyGenType(IntEnum):
|
|
186
|
-
"""Type of the key to generate"""
|
|
194
|
+
"""Type of the key to generate."""
|
|
187
195
|
|
|
188
196
|
DEFAULT = 0
|
|
189
197
|
RSA2048 = 1
|
|
@@ -193,21 +201,21 @@ class KeyGenType(IntEnum):
|
|
|
193
201
|
|
|
194
202
|
# "Lp" means "login parameters"
|
|
195
203
|
class LpAuthFlag(IntEnum):
|
|
196
|
-
"""Authorization flags"""
|
|
204
|
+
"""Authorization flags."""
|
|
197
205
|
|
|
198
206
|
OAUTH2 = 0x2
|
|
199
207
|
NORMAL = 0x4
|
|
200
208
|
|
|
201
209
|
|
|
202
210
|
class MediaQuality(IntEnum):
|
|
203
|
-
"""Media quality setting"""
|
|
211
|
+
"""Media quality setting."""
|
|
204
212
|
|
|
205
213
|
BALANCED = 0
|
|
206
214
|
WORSE = 1
|
|
207
215
|
|
|
208
216
|
|
|
209
217
|
class ProviderStatus(IntEnum):
|
|
210
|
-
"""Provider status according to manual testing"""
|
|
218
|
+
"""Provider status according to manual testing."""
|
|
211
219
|
|
|
212
220
|
OK = 1
|
|
213
221
|
PREPARATION = 2
|
|
@@ -215,7 +223,7 @@ class ProviderStatus(IntEnum):
|
|
|
215
223
|
|
|
216
224
|
|
|
217
225
|
class PushNotifyState(IntEnum):
|
|
218
|
-
"""Push notifications state"""
|
|
226
|
+
"""Push notifications state."""
|
|
219
227
|
|
|
220
228
|
NOT_CONNECTED = 0
|
|
221
229
|
HEARTBEAT = 1
|
|
@@ -223,7 +231,7 @@ class PushNotifyState(IntEnum):
|
|
|
223
231
|
|
|
224
232
|
|
|
225
233
|
class ShowEmails(IntEnum):
|
|
226
|
-
"""Show emails mode"""
|
|
234
|
+
"""Show emails mode."""
|
|
227
235
|
|
|
228
236
|
OFF = 0
|
|
229
237
|
ACCEPTED_CONTACTS = 1
|
|
@@ -231,7 +239,7 @@ class ShowEmails(IntEnum):
|
|
|
231
239
|
|
|
232
240
|
|
|
233
241
|
class SocketSecurity(IntEnum):
|
|
234
|
-
"""Socket security"""
|
|
242
|
+
"""Socket security."""
|
|
235
243
|
|
|
236
244
|
AUTOMATIC = 0
|
|
237
245
|
SSL = 1
|
|
@@ -240,7 +248,7 @@ class SocketSecurity(IntEnum):
|
|
|
240
248
|
|
|
241
249
|
|
|
242
250
|
class VideochatType(IntEnum):
|
|
243
|
-
"""Video chat URL type"""
|
|
251
|
+
"""Video chat URL type."""
|
|
244
252
|
|
|
245
253
|
UNKNOWN = 0
|
|
246
254
|
BASICWEBRTC = 1
|
{deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/contact.py
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Contact module."""
|
|
2
|
+
|
|
1
3
|
from dataclasses import dataclass
|
|
2
4
|
from typing import TYPE_CHECKING
|
|
3
5
|
|
|
@@ -11,8 +13,7 @@ if TYPE_CHECKING:
|
|
|
11
13
|
|
|
12
14
|
@dataclass
|
|
13
15
|
class Contact:
|
|
14
|
-
"""
|
|
15
|
-
Contact API.
|
|
16
|
+
"""Contact API.
|
|
16
17
|
|
|
17
18
|
Essentially a wrapper for RPC, account ID and a contact ID.
|
|
18
19
|
"""
|
|
@@ -45,8 +46,9 @@ class Contact:
|
|
|
45
46
|
self._rpc.change_contact_name(self.account.id, self.id, name)
|
|
46
47
|
|
|
47
48
|
def get_encryption_info(self) -> str:
|
|
48
|
-
"""Get a multi-line encryption info
|
|
49
|
-
|
|
49
|
+
"""Get a multi-line encryption info.
|
|
50
|
+
|
|
51
|
+
Encryption info contains your fingerprint and the fingerprint of the contact.
|
|
50
52
|
"""
|
|
51
53
|
return self._rpc.get_contact_encryption_info(self.account.id, self.id)
|
|
52
54
|
|
|
@@ -66,4 +68,5 @@ class Contact:
|
|
|
66
68
|
)
|
|
67
69
|
|
|
68
70
|
def make_vcard(self) -> str:
|
|
71
|
+
"""Make a vCard for the contact."""
|
|
69
72
|
return self.account.make_vcard([self])
|
{deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/deltachat.py
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Account manager module."""
|
|
2
|
+
|
|
1
3
|
from __future__ import annotations
|
|
2
4
|
|
|
3
5
|
from typing import TYPE_CHECKING
|
|
@@ -10,12 +12,13 @@ if TYPE_CHECKING:
|
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
class DeltaChat:
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
+
"""Delta Chat accounts manager.
|
|
16
|
+
|
|
15
17
|
This is the root of the object oriented API.
|
|
16
18
|
"""
|
|
17
19
|
|
|
18
20
|
def __init__(self, rpc: "Rpc") -> None:
|
|
21
|
+
"""Initialize account manager."""
|
|
19
22
|
self.rpc = rpc
|
|
20
23
|
|
|
21
24
|
def add_account(self) -> Account:
|
|
@@ -37,9 +40,7 @@ class DeltaChat:
|
|
|
37
40
|
self.rpc.stop_io_for_all_accounts()
|
|
38
41
|
|
|
39
42
|
def maybe_network(self) -> None:
|
|
40
|
-
"""Indicate that the network
|
|
41
|
-
conditions might have changed.
|
|
42
|
-
"""
|
|
43
|
+
"""Indicate that the network conditions might have changed."""
|
|
43
44
|
self.rpc.maybe_network()
|
|
44
45
|
|
|
45
46
|
def get_system_info(self) -> AttrDict:
|
{deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/events.py
RENAMED
|
@@ -36,7 +36,7 @@ class EventFilter(ABC):
|
|
|
36
36
|
|
|
37
37
|
@abstractmethod
|
|
38
38
|
def __hash__(self) -> int:
|
|
39
|
-
"""Object's unique hash"""
|
|
39
|
+
"""Object's unique hash."""
|
|
40
40
|
|
|
41
41
|
@abstractmethod
|
|
42
42
|
def __eq__(self, other) -> bool:
|
|
@@ -52,9 +52,7 @@ class EventFilter(ABC):
|
|
|
52
52
|
|
|
53
53
|
@abstractmethod
|
|
54
54
|
def filter(self, event):
|
|
55
|
-
"""Return True-like value if the event passed the filter
|
|
56
|
-
used, or False-like value otherwise.
|
|
57
|
-
"""
|
|
55
|
+
"""Return True-like value if the event passed the filter."""
|
|
58
56
|
|
|
59
57
|
|
|
60
58
|
class RawEvent(EventFilter):
|
|
@@ -82,31 +80,17 @@ class RawEvent(EventFilter):
|
|
|
82
80
|
return False
|
|
83
81
|
|
|
84
82
|
def filter(self, event: "AttrDict") -> bool:
|
|
83
|
+
"""Filter an event.
|
|
84
|
+
|
|
85
|
+
Return true if the event should be processed.
|
|
86
|
+
"""
|
|
85
87
|
if self.types and event.kind not in self.types:
|
|
86
88
|
return False
|
|
87
89
|
return self._call_func(event)
|
|
88
90
|
|
|
89
91
|
|
|
90
92
|
class NewMessage(EventFilter):
|
|
91
|
-
"""Matches whenever a new message arrives.
|
|
92
|
-
|
|
93
|
-
Warning: registering a handler for this event will cause the messages
|
|
94
|
-
to be marked as read. Its usage is mainly intended for bots.
|
|
95
|
-
|
|
96
|
-
:param pattern: if set, this Pattern will be used to filter the message by its text
|
|
97
|
-
content.
|
|
98
|
-
:param command: If set, only match messages with the given command (ex. /help).
|
|
99
|
-
Setting this property implies `is_info==False`.
|
|
100
|
-
:param is_bot: If set to True only match messages sent by bots, if set to None
|
|
101
|
-
match messages from bots and users. If omitted or set to False
|
|
102
|
-
only messages from users will be matched.
|
|
103
|
-
:param is_info: If set to True only match info/system messages, if set to False
|
|
104
|
-
only match messages that are not info/system messages. If omitted
|
|
105
|
-
info/system messages as well as normal messages will be matched.
|
|
106
|
-
:param func: A Callable function that should accept the event as input
|
|
107
|
-
parameter, and return a bool value indicating whether the event
|
|
108
|
-
should be dispatched or not.
|
|
109
|
-
"""
|
|
93
|
+
"""Matches whenever a new message arrives."""
|
|
110
94
|
|
|
111
95
|
def __init__(
|
|
112
96
|
self,
|
|
@@ -121,6 +105,25 @@ class NewMessage(EventFilter):
|
|
|
121
105
|
is_info: Optional[bool] = None,
|
|
122
106
|
func: Optional[Callable[["AttrDict"], bool]] = None,
|
|
123
107
|
) -> None:
|
|
108
|
+
"""Initialize a new message filter.
|
|
109
|
+
|
|
110
|
+
Warning: registering a handler for this event will cause the messages
|
|
111
|
+
to be marked as read. Its usage is mainly intended for bots.
|
|
112
|
+
|
|
113
|
+
:param pattern: if set, this Pattern will be used to filter the message by its text
|
|
114
|
+
content.
|
|
115
|
+
:param command: If set, only match messages with the given command (ex. /help).
|
|
116
|
+
Setting this property implies `is_info==False`.
|
|
117
|
+
:param is_bot: If set to True only match messages sent by bots, if set to None
|
|
118
|
+
match messages from bots and users. If omitted or set to False
|
|
119
|
+
only messages from users will be matched.
|
|
120
|
+
:param is_info: If set to True only match info/system messages, if set to False
|
|
121
|
+
only match messages that are not info/system messages. If omitted
|
|
122
|
+
info/system messages as well as normal messages will be matched.
|
|
123
|
+
:param func: A Callable function that should accept the event as input
|
|
124
|
+
parameter, and return a bool value indicating whether the event
|
|
125
|
+
should be dispatched or not.
|
|
126
|
+
"""
|
|
124
127
|
super().__init__(func=func)
|
|
125
128
|
self.is_bot = is_bot
|
|
126
129
|
self.is_info = is_info
|
|
@@ -159,6 +162,7 @@ class NewMessage(EventFilter):
|
|
|
159
162
|
return False
|
|
160
163
|
|
|
161
164
|
def filter(self, event: "AttrDict") -> bool:
|
|
165
|
+
"""Return true if if the event is a new message event."""
|
|
162
166
|
if self.is_bot is not None and self.is_bot != event.message_snapshot.is_bot:
|
|
163
167
|
return False
|
|
164
168
|
if self.is_info is not None and self.is_info != event.message_snapshot.is_info:
|
|
@@ -199,6 +203,7 @@ class MemberListChanged(EventFilter):
|
|
|
199
203
|
return False
|
|
200
204
|
|
|
201
205
|
def filter(self, event: "AttrDict") -> bool:
|
|
206
|
+
"""Return true if if the event is a member addition event."""
|
|
202
207
|
if self.added is not None and self.added != event.member_added:
|
|
203
208
|
return False
|
|
204
209
|
return self._call_func(event)
|
|
@@ -231,6 +236,7 @@ class GroupImageChanged(EventFilter):
|
|
|
231
236
|
return False
|
|
232
237
|
|
|
233
238
|
def filter(self, event: "AttrDict") -> bool:
|
|
239
|
+
"""Return True if event is matched."""
|
|
234
240
|
if self.deleted is not None and self.deleted != event.image_deleted:
|
|
235
241
|
return False
|
|
236
242
|
return self._call_func(event)
|
|
@@ -256,13 +262,12 @@ class GroupNameChanged(EventFilter):
|
|
|
256
262
|
return False
|
|
257
263
|
|
|
258
264
|
def filter(self, event: "AttrDict") -> bool:
|
|
265
|
+
"""Return True if event is matched."""
|
|
259
266
|
return self._call_func(event)
|
|
260
267
|
|
|
261
268
|
|
|
262
269
|
class HookCollection:
|
|
263
|
-
"""
|
|
264
|
-
Helper class to collect event hooks that can later be added to a Delta Chat client.
|
|
265
|
-
"""
|
|
270
|
+
"""Helper class to collect event hooks that can later be added to a Delta Chat client."""
|
|
266
271
|
|
|
267
272
|
def __init__(self) -> None:
|
|
268
273
|
self._hooks: set[tuple[Callable, Union[type, EventFilter]]] = set()
|
{deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/message.py
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Message module."""
|
|
2
|
+
|
|
1
3
|
import json
|
|
2
4
|
from dataclasses import dataclass
|
|
3
5
|
from typing import TYPE_CHECKING, Optional, Union
|
|
@@ -45,6 +47,7 @@ class Message:
|
|
|
45
47
|
return None
|
|
46
48
|
|
|
47
49
|
def get_sender_contact(self) -> Contact:
|
|
50
|
+
"""Return sender contact."""
|
|
48
51
|
from_id = self.get_snapshot().from_id
|
|
49
52
|
return self.account.get_contact_by_id(from_id)
|
|
50
53
|
|
|
@@ -53,6 +56,11 @@ class Message:
|
|
|
53
56
|
self._rpc.markseen_msgs(self.account.id, [self.id])
|
|
54
57
|
|
|
55
58
|
def continue_autocrypt_key_transfer(self, setup_code: str) -> None:
|
|
59
|
+
"""Continue the Autocrypt Setup Message key transfer.
|
|
60
|
+
|
|
61
|
+
This function can be called on received Autocrypt Setup Message
|
|
62
|
+
to import the key encrypted with the provided setup code.
|
|
63
|
+
"""
|
|
56
64
|
self._rpc.continue_autocrypt_key_transfer(self.account.id, self.id, setup_code)
|
|
57
65
|
|
|
58
66
|
def send_webxdc_status_update(self, update: Union[dict, str], description: str) -> None:
|
|
@@ -62,6 +70,7 @@ class Message:
|
|
|
62
70
|
self._rpc.send_webxdc_status_update(self.account.id, self.id, update, description)
|
|
63
71
|
|
|
64
72
|
def get_webxdc_status_updates(self, last_known_serial: int = 0) -> list:
|
|
73
|
+
"""Return a list of Webxdc status updates for Webxdc instance message."""
|
|
65
74
|
return json.loads(self._rpc.get_webxdc_status_updates(self.account.id, self.id, last_known_serial))
|
|
66
75
|
|
|
67
76
|
def get_info(self) -> str:
|
|
@@ -69,6 +78,7 @@ class Message:
|
|
|
69
78
|
return self._rpc.get_message_info(self.account.id, self.id)
|
|
70
79
|
|
|
71
80
|
def get_webxdc_info(self) -> dict:
|
|
81
|
+
"""Get info from a Webxdc message in JSON format."""
|
|
72
82
|
return self._rpc.get_webxdc_info(self.account.id, self.id)
|
|
73
83
|
|
|
74
84
|
def wait_until_delivered(self) -> None:
|
|
@@ -80,8 +90,10 @@ class Message:
|
|
|
80
90
|
|
|
81
91
|
@futuremethod
|
|
82
92
|
def send_webxdc_realtime_advertisement(self):
|
|
93
|
+
"""Send an advertisement to join the realtime channel."""
|
|
83
94
|
yield self._rpc.send_webxdc_realtime_advertisement.future(self.account.id, self.id)
|
|
84
95
|
|
|
85
96
|
@futuremethod
|
|
86
97
|
def send_webxdc_realtime_data(self, data) -> None:
|
|
98
|
+
"""Send data to the realtime channel."""
|
|
87
99
|
yield self._rpc.send_webxdc_realtime_data.future(self.account.id, self.id, list(data))
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Pytest plugin module."""
|
|
2
|
+
|
|
1
3
|
from __future__ import annotations
|
|
2
4
|
|
|
3
5
|
import os
|
|
@@ -13,24 +15,30 @@ from .rpc import Rpc
|
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
class ACFactory:
|
|
18
|
+
"""Test account factory."""
|
|
19
|
+
|
|
16
20
|
def __init__(self, deltachat: DeltaChat) -> None:
|
|
17
21
|
self.deltachat = deltachat
|
|
18
22
|
|
|
19
23
|
def get_unconfigured_account(self) -> Account:
|
|
24
|
+
"""Create a new unconfigured account."""
|
|
20
25
|
account = self.deltachat.add_account()
|
|
21
26
|
account.set_config("verified_one_on_one_chats", "1")
|
|
22
27
|
return account
|
|
23
28
|
|
|
24
29
|
def get_unconfigured_bot(self) -> Bot:
|
|
30
|
+
"""Create a new unconfigured bot."""
|
|
25
31
|
return Bot(self.get_unconfigured_account())
|
|
26
32
|
|
|
27
33
|
def get_credentials(self) -> (str, str):
|
|
34
|
+
"""Generate new credentials for chatmail account."""
|
|
28
35
|
domain = os.getenv("CHATMAIL_DOMAIN")
|
|
29
36
|
username = "ci-" + "".join(random.choice("2345789acdefghjkmnpqrstuvwxyz") for i in range(6))
|
|
30
37
|
return f"{username}@{domain}", f"{username}${username}"
|
|
31
38
|
|
|
32
39
|
@futuremethod
|
|
33
40
|
def new_configured_account(self):
|
|
41
|
+
"""Create a new configured account."""
|
|
34
42
|
addr, password = self.get_credentials()
|
|
35
43
|
account = self.get_unconfigured_account()
|
|
36
44
|
params = {"addr": addr, "password": password}
|
|
@@ -40,6 +48,7 @@ class ACFactory:
|
|
|
40
48
|
return account
|
|
41
49
|
|
|
42
50
|
def new_configured_bot(self) -> Bot:
|
|
51
|
+
"""Create a new configured bot."""
|
|
43
52
|
addr, password = self.get_credentials()
|
|
44
53
|
bot = self.get_unconfigured_bot()
|
|
45
54
|
bot.configure(addr, password)
|
|
@@ -47,11 +56,13 @@ class ACFactory:
|
|
|
47
56
|
|
|
48
57
|
@futuremethod
|
|
49
58
|
def get_online_account(self):
|
|
59
|
+
"""Create a new account and start I/O."""
|
|
50
60
|
account = yield self.new_configured_account.future()
|
|
51
61
|
account.bring_online()
|
|
52
62
|
return account
|
|
53
63
|
|
|
54
64
|
def get_online_accounts(self, num: int) -> list[Account]:
|
|
65
|
+
"""Create multiple online accounts."""
|
|
55
66
|
futures = [self.get_online_account.future() for _ in range(num)]
|
|
56
67
|
return [f() for f in futures]
|
|
57
68
|
|
|
@@ -66,6 +77,10 @@ class ACFactory:
|
|
|
66
77
|
return ac_clone
|
|
67
78
|
|
|
68
79
|
def get_accepted_chat(self, ac1: Account, ac2: Account) -> Chat:
|
|
80
|
+
"""Create a new 1:1 chat between ac1 and ac2 accepted on both sides.
|
|
81
|
+
|
|
82
|
+
Returned chat is a chat with ac2 from ac1 point of view.
|
|
83
|
+
"""
|
|
69
84
|
ac2.create_chat(ac1)
|
|
70
85
|
return ac1.create_chat(ac2)
|
|
71
86
|
|
|
@@ -77,6 +92,7 @@ class ACFactory:
|
|
|
77
92
|
file: Optional[str] = None,
|
|
78
93
|
group: Optional[str] = None,
|
|
79
94
|
) -> Message:
|
|
95
|
+
"""Send a message."""
|
|
80
96
|
if not from_account:
|
|
81
97
|
from_account = (self.get_online_accounts(1))[0]
|
|
82
98
|
to_contact = from_account.create_contact(to_account)
|
|
@@ -95,6 +111,7 @@ class ACFactory:
|
|
|
95
111
|
file: Optional[str] = None,
|
|
96
112
|
group: Optional[str] = None,
|
|
97
113
|
) -> AttrDict:
|
|
114
|
+
"""Send a message and wait until recipient processes it."""
|
|
98
115
|
self.send_message(
|
|
99
116
|
to_account=to_client.account,
|
|
100
117
|
from_account=from_account,
|
|
@@ -108,6 +125,7 @@ class ACFactory:
|
|
|
108
125
|
|
|
109
126
|
@pytest.fixture
|
|
110
127
|
def rpc(tmp_path) -> AsyncGenerator:
|
|
128
|
+
"""RPC client fixture."""
|
|
111
129
|
rpc_server = Rpc(accounts_dir=str(tmp_path / "accounts"))
|
|
112
130
|
with rpc_server:
|
|
113
131
|
yield rpc_server
|
|
@@ -115,6 +133,7 @@ def rpc(tmp_path) -> AsyncGenerator:
|
|
|
115
133
|
|
|
116
134
|
@pytest.fixture
|
|
117
135
|
def acfactory(rpc) -> AsyncGenerator:
|
|
136
|
+
"""Return account factory fixture."""
|
|
118
137
|
return ACFactory(DeltaChat(rpc))
|
|
119
138
|
|
|
120
139
|
|
|
@@ -132,7 +151,7 @@ def data():
|
|
|
132
151
|
raise Exception("Data path cannot be found")
|
|
133
152
|
|
|
134
153
|
def get_path(self, bn):
|
|
135
|
-
"""
|
|
154
|
+
"""Return path of file or None if it doesn't exist."""
|
|
136
155
|
fn = os.path.join(self.path, *bn.split("/"))
|
|
137
156
|
assert os.path.exists(fn)
|
|
138
157
|
return fn
|
{deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/rpc.py
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""JSON-RPC client module."""
|
|
2
|
+
|
|
1
3
|
from __future__ import annotations
|
|
2
4
|
|
|
3
5
|
import itertools
|
|
@@ -12,16 +14,19 @@ from typing import Any, Iterator, Optional
|
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
class JsonRpcError(Exception):
|
|
15
|
-
|
|
17
|
+
"""JSON-RPC error."""
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
class RpcFuture:
|
|
21
|
+
"""RPC future waiting for RPC call result."""
|
|
22
|
+
|
|
19
23
|
def __init__(self, rpc: "Rpc", request_id: int, event: Event):
|
|
20
24
|
self.rpc = rpc
|
|
21
25
|
self.request_id = request_id
|
|
22
26
|
self.event = event
|
|
23
27
|
|
|
24
28
|
def __call__(self):
|
|
29
|
+
"""Wait for the future to return the result."""
|
|
25
30
|
self.event.wait()
|
|
26
31
|
response = self.rpc.request_results.pop(self.request_id)
|
|
27
32
|
if "error" in response:
|
|
@@ -32,17 +37,19 @@ class RpcFuture:
|
|
|
32
37
|
|
|
33
38
|
|
|
34
39
|
class RpcMethod:
|
|
40
|
+
"""RPC method."""
|
|
41
|
+
|
|
35
42
|
def __init__(self, rpc: "Rpc", name: str):
|
|
36
43
|
self.rpc = rpc
|
|
37
44
|
self.name = name
|
|
38
45
|
|
|
39
46
|
def __call__(self, *args) -> Any:
|
|
40
|
-
"""
|
|
47
|
+
"""Call JSON-RPC method synchronously."""
|
|
41
48
|
future = self.future(*args)
|
|
42
49
|
return future()
|
|
43
50
|
|
|
44
51
|
def future(self, *args) -> Any:
|
|
45
|
-
"""
|
|
52
|
+
"""Call JSON-RPC method asynchronously."""
|
|
46
53
|
request_id = next(self.rpc.id_iterator)
|
|
47
54
|
request = {
|
|
48
55
|
"jsonrpc": "2.0",
|
|
@@ -58,8 +65,13 @@ class RpcMethod:
|
|
|
58
65
|
|
|
59
66
|
|
|
60
67
|
class Rpc:
|
|
68
|
+
"""RPC client."""
|
|
69
|
+
|
|
61
70
|
def __init__(self, accounts_dir: Optional[str] = None, **kwargs):
|
|
62
|
-
"""
|
|
71
|
+
"""Initialize RPC client.
|
|
72
|
+
|
|
73
|
+
The given arguments will be passed to subprocess.Popen().
|
|
74
|
+
"""
|
|
63
75
|
if accounts_dir:
|
|
64
76
|
kwargs["env"] = {
|
|
65
77
|
**kwargs.get("env", os.environ),
|
|
@@ -81,6 +93,7 @@ class Rpc:
|
|
|
81
93
|
self.events_thread: Thread
|
|
82
94
|
|
|
83
95
|
def start(self) -> None:
|
|
96
|
+
"""Start RPC server subprocess."""
|
|
84
97
|
if sys.version_info >= (3, 11):
|
|
85
98
|
self.process = subprocess.Popen(
|
|
86
99
|
"deltachat-rpc-server",
|
|
@@ -130,6 +143,7 @@ class Rpc:
|
|
|
130
143
|
self.close()
|
|
131
144
|
|
|
132
145
|
def reader_loop(self) -> None:
|
|
146
|
+
"""Process JSON-RPC responses from the RPC server process output."""
|
|
133
147
|
try:
|
|
134
148
|
while line := self.process.stdout.readline():
|
|
135
149
|
response = json.loads(line)
|
|
@@ -157,12 +171,13 @@ class Rpc:
|
|
|
157
171
|
logging.exception("Exception in the writer loop")
|
|
158
172
|
|
|
159
173
|
def get_queue(self, account_id: int) -> Queue:
|
|
174
|
+
"""Get event queue corresponding to the given account ID."""
|
|
160
175
|
if account_id not in self.event_queues:
|
|
161
176
|
self.event_queues[account_id] = Queue()
|
|
162
177
|
return self.event_queues[account_id]
|
|
163
178
|
|
|
164
179
|
def events_loop(self) -> None:
|
|
165
|
-
"""
|
|
180
|
+
"""Request new events and distributes them between queues."""
|
|
166
181
|
try:
|
|
167
182
|
while True:
|
|
168
183
|
if self.closing:
|
|
@@ -178,12 +193,12 @@ class Rpc:
|
|
|
178
193
|
logging.exception("Exception in the event loop")
|
|
179
194
|
|
|
180
195
|
def wait_for_event(self, account_id: int) -> Optional[dict]:
|
|
181
|
-
"""
|
|
196
|
+
"""Wait for the next event from the given account and returns it."""
|
|
182
197
|
queue = self.get_queue(account_id)
|
|
183
198
|
return queue.get()
|
|
184
199
|
|
|
185
200
|
def clear_all_events(self, account_id: int):
|
|
186
|
-
"""
|
|
201
|
+
"""Remove all queued-up events for a given account. Useful for tests."""
|
|
187
202
|
queue = self.get_queue(account_id)
|
|
188
203
|
try:
|
|
189
204
|
while True:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deltachat_rpc_client-1.159.3 → deltachat_rpc_client-1.159.5}/src/deltachat_rpc_client/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|