deltachat-rpc-client 1.157.2__py3-none-any.whl → 1.158.0__py3-none-any.whl
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/account.py +28 -37
- deltachat_rpc_client/pytestplugin.py +59 -20
- {deltachat_rpc_client-1.157.2.dist-info → deltachat_rpc_client-1.158.0.dist-info}/METADATA +3 -2
- {deltachat_rpc_client-1.157.2.dist-info → deltachat_rpc_client-1.158.0.dist-info}/RECORD +8 -8
- {deltachat_rpc_client-1.157.2.dist-info → deltachat_rpc_client-1.158.0.dist-info}/WHEEL +1 -1
- {deltachat_rpc_client-1.157.2.dist-info → deltachat_rpc_client-1.158.0.dist-info}/entry_points.txt +0 -0
- {deltachat_rpc_client-1.157.2.dist-info → deltachat_rpc_client-1.158.0.dist-info/licenses}/LICENSE +0 -0
- {deltachat_rpc_client-1.157.2.dist-info → deltachat_rpc_client-1.158.0.dist-info}/top_level.txt +0 -0
deltachat_rpc_client/account.py
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from tempfile import TemporaryDirectory
|
|
6
4
|
from typing import TYPE_CHECKING, Optional, Union
|
|
7
5
|
from warnings import warn
|
|
8
6
|
|
|
@@ -28,9 +26,12 @@ class Account:
|
|
|
28
26
|
def _rpc(self) -> "Rpc":
|
|
29
27
|
return self.manager.rpc
|
|
30
28
|
|
|
31
|
-
def wait_for_event(self) -> AttrDict:
|
|
29
|
+
def wait_for_event(self, event_type=None) -> AttrDict:
|
|
32
30
|
"""Wait until the next event and return it."""
|
|
33
|
-
|
|
31
|
+
while True:
|
|
32
|
+
next_event = AttrDict(self._rpc.wait_for_event(self.id))
|
|
33
|
+
if event_type is None or next_event.kind == event_type:
|
|
34
|
+
return next_event
|
|
34
35
|
|
|
35
36
|
def clear_all_events(self):
|
|
36
37
|
"""Removes all queued-up events for a given account. Useful for tests."""
|
|
@@ -41,14 +42,14 @@ class Account:
|
|
|
41
42
|
self._rpc.remove_account(self.id)
|
|
42
43
|
|
|
43
44
|
def clone(self) -> "Account":
|
|
44
|
-
"""Clone given account.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
"""Clone given account.
|
|
46
|
+
This uses backup-transfer via iroh, i.e. the 'Add second device' feature."""
|
|
47
|
+
future = self._rpc.provide_backup.future(self.id)
|
|
48
|
+
qr = self._rpc.get_backup_qr(self.id)
|
|
49
|
+
new_account = self.manager.add_account()
|
|
50
|
+
new_account._rpc.get_backup(new_account.id, qr)
|
|
51
|
+
future()
|
|
52
|
+
return new_account
|
|
52
53
|
|
|
53
54
|
def start_io(self) -> None:
|
|
54
55
|
"""Start the account I/O."""
|
|
@@ -112,12 +113,9 @@ class Account:
|
|
|
112
113
|
def bring_online(self):
|
|
113
114
|
"""Start I/O and wait until IMAP becomes IDLE."""
|
|
114
115
|
self.start_io()
|
|
115
|
-
|
|
116
|
-
event = self.wait_for_event()
|
|
117
|
-
if event.kind == EventType.IMAP_INBOX_IDLE:
|
|
118
|
-
break
|
|
116
|
+
self.wait_for_event(EventType.IMAP_INBOX_IDLE)
|
|
119
117
|
|
|
120
|
-
def create_contact(self, obj: Union[int, str, Contact], name: Optional[str] = None) -> Contact:
|
|
118
|
+
def create_contact(self, obj: Union[int, str, Contact, "Account"], name: Optional[str] = None) -> Contact:
|
|
121
119
|
"""Create a new Contact or return an existing one.
|
|
122
120
|
|
|
123
121
|
Calling this method will always result in the same
|
|
@@ -125,9 +123,15 @@ class Account:
|
|
|
125
123
|
with that e-mail address, it is unblocked and its display
|
|
126
124
|
name is updated if specified.
|
|
127
125
|
|
|
128
|
-
:param obj: email-address
|
|
126
|
+
:param obj: email-address, contact id or account.
|
|
129
127
|
:param name: (optional) display name for this contact.
|
|
130
128
|
"""
|
|
129
|
+
if isinstance(obj, Account):
|
|
130
|
+
vcard = obj.self_contact.make_vcard()
|
|
131
|
+
[contact] = self.import_vcard(vcard)
|
|
132
|
+
if name:
|
|
133
|
+
contact.set_name(name)
|
|
134
|
+
return contact
|
|
131
135
|
if isinstance(obj, int):
|
|
132
136
|
obj = Contact(self, obj)
|
|
133
137
|
if isinstance(obj, Contact):
|
|
@@ -148,9 +152,8 @@ class Account:
|
|
|
148
152
|
return [Contact(self, contact_id) for contact_id in contact_ids]
|
|
149
153
|
|
|
150
154
|
def create_chat(self, account: "Account") -> Chat:
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
return contact.create_chat()
|
|
155
|
+
"""Create a 1:1 chat with another account."""
|
|
156
|
+
return self.create_contact(account).create_chat()
|
|
154
157
|
|
|
155
158
|
def get_device_chat(self) -> Chat:
|
|
156
159
|
"""Return device chat."""
|
|
@@ -334,24 +337,15 @@ class Account:
|
|
|
334
337
|
|
|
335
338
|
def wait_for_incoming_msg_event(self):
|
|
336
339
|
"""Wait for incoming message event and return it."""
|
|
337
|
-
|
|
338
|
-
event = self.wait_for_event()
|
|
339
|
-
if event.kind == EventType.INCOMING_MSG:
|
|
340
|
-
return event
|
|
340
|
+
return self.wait_for_event(EventType.INCOMING_MSG)
|
|
341
341
|
|
|
342
342
|
def wait_for_msgs_changed_event(self):
|
|
343
343
|
"""Wait for messages changed event and return it."""
|
|
344
|
-
|
|
345
|
-
event = self.wait_for_event()
|
|
346
|
-
if event.kind == EventType.MSGS_CHANGED:
|
|
347
|
-
return event
|
|
344
|
+
return self.wait_for_event(EventType.MSGS_CHANGED)
|
|
348
345
|
|
|
349
346
|
def wait_for_msgs_noticed_event(self):
|
|
350
347
|
"""Wait for messages noticed event and return it."""
|
|
351
|
-
|
|
352
|
-
event = self.wait_for_event()
|
|
353
|
-
if event.kind == EventType.MSGS_NOTICED:
|
|
354
|
-
return event
|
|
348
|
+
return self.wait_for_event(EventType.MSGS_NOTICED)
|
|
355
349
|
|
|
356
350
|
def wait_for_incoming_msg(self):
|
|
357
351
|
"""Wait for incoming message and return it.
|
|
@@ -372,10 +366,7 @@ class Account:
|
|
|
372
366
|
break
|
|
373
367
|
|
|
374
368
|
def wait_for_reactions_changed(self):
|
|
375
|
-
|
|
376
|
-
event = self.wait_for_event()
|
|
377
|
-
if event.kind == EventType.REACTIONS_CHANGED:
|
|
378
|
-
return event
|
|
369
|
+
return self.wait_for_event(EventType.REACTIONS_CHANGED)
|
|
379
370
|
|
|
380
371
|
def get_fresh_messages_in_arrival_order(self) -> list[Message]:
|
|
381
372
|
"""Return fresh messages list sorted in the order of their arrival, with ascending IDs."""
|
|
@@ -4,6 +4,7 @@ import os
|
|
|
4
4
|
import random
|
|
5
5
|
from typing import AsyncGenerator, Optional
|
|
6
6
|
|
|
7
|
+
import py
|
|
7
8
|
import pytest
|
|
8
9
|
|
|
9
10
|
from . import Account, AttrDict, Bot, Chat, Client, DeltaChat, EventType, Message
|
|
@@ -11,14 +12,6 @@ from ._utils import futuremethod
|
|
|
11
12
|
from .rpc import Rpc
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
def get_temp_credentials() -> dict:
|
|
15
|
-
domain = os.getenv("CHATMAIL_DOMAIN")
|
|
16
|
-
username = "ci-" + "".join(random.choice("2345789acdefghjkmnpqrstuvwxyz") for i in range(6))
|
|
17
|
-
password = f"{username}${username}"
|
|
18
|
-
addr = f"{username}@{domain}"
|
|
19
|
-
return {"email": addr, "password": password}
|
|
20
|
-
|
|
21
|
-
|
|
22
15
|
class ACFactory:
|
|
23
16
|
def __init__(self, deltachat: DeltaChat) -> None:
|
|
24
17
|
self.deltachat = deltachat
|
|
@@ -31,26 +24,25 @@ class ACFactory:
|
|
|
31
24
|
def get_unconfigured_bot(self) -> Bot:
|
|
32
25
|
return Bot(self.get_unconfigured_account())
|
|
33
26
|
|
|
34
|
-
def
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
account.set_config("addr", credentials["email"])
|
|
39
|
-
account.set_config("mail_pw", credentials["password"])
|
|
40
|
-
assert not account.is_configured()
|
|
41
|
-
return account
|
|
27
|
+
def get_credentials(self) -> (str, str):
|
|
28
|
+
domain = os.getenv("CHATMAIL_DOMAIN")
|
|
29
|
+
username = "ci-" + "".join(random.choice("2345789acdefghjkmnpqrstuvwxyz") for i in range(6))
|
|
30
|
+
return f"{username}@{domain}", f"{username}${username}"
|
|
42
31
|
|
|
43
32
|
@futuremethod
|
|
44
33
|
def new_configured_account(self):
|
|
45
|
-
|
|
46
|
-
|
|
34
|
+
addr, password = self.get_credentials()
|
|
35
|
+
account = self.get_unconfigured_account()
|
|
36
|
+
params = {"addr": addr, "password": password}
|
|
37
|
+
yield account._rpc.add_transport.future(account.id, params)
|
|
38
|
+
|
|
47
39
|
assert account.is_configured()
|
|
48
40
|
return account
|
|
49
41
|
|
|
50
42
|
def new_configured_bot(self) -> Bot:
|
|
51
|
-
|
|
43
|
+
addr, password = self.get_credentials()
|
|
52
44
|
bot = self.get_unconfigured_bot()
|
|
53
|
-
bot.configure(
|
|
45
|
+
bot.configure(addr, password)
|
|
54
46
|
return bot
|
|
55
47
|
|
|
56
48
|
@futuremethod
|
|
@@ -124,3 +116,50 @@ def rpc(tmp_path) -> AsyncGenerator:
|
|
|
124
116
|
@pytest.fixture
|
|
125
117
|
def acfactory(rpc) -> AsyncGenerator:
|
|
126
118
|
return ACFactory(DeltaChat(rpc))
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@pytest.fixture
|
|
122
|
+
def data():
|
|
123
|
+
"""Test data."""
|
|
124
|
+
|
|
125
|
+
class Data:
|
|
126
|
+
def __init__(self) -> None:
|
|
127
|
+
for path in reversed(py.path.local(__file__).parts()):
|
|
128
|
+
datadir = path.join("test-data")
|
|
129
|
+
if datadir.isdir():
|
|
130
|
+
self.path = datadir
|
|
131
|
+
return
|
|
132
|
+
raise Exception("Data path cannot be found")
|
|
133
|
+
|
|
134
|
+
def get_path(self, bn):
|
|
135
|
+
"""return path of file or None if it doesn't exist."""
|
|
136
|
+
fn = os.path.join(self.path, *bn.split("/"))
|
|
137
|
+
assert os.path.exists(fn)
|
|
138
|
+
return fn
|
|
139
|
+
|
|
140
|
+
def read_path(self, bn, mode="r"):
|
|
141
|
+
fn = self.get_path(bn)
|
|
142
|
+
if fn is not None:
|
|
143
|
+
with open(fn, mode) as f:
|
|
144
|
+
return f.read()
|
|
145
|
+
return None
|
|
146
|
+
|
|
147
|
+
return Data()
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@pytest.fixture
|
|
151
|
+
def log():
|
|
152
|
+
"""Log printer fixture."""
|
|
153
|
+
|
|
154
|
+
class Printer:
|
|
155
|
+
def section(self, msg: str) -> None:
|
|
156
|
+
print()
|
|
157
|
+
print("=" * 10, msg, "=" * 10)
|
|
158
|
+
|
|
159
|
+
def step(self, msg: str) -> None:
|
|
160
|
+
print("-" * 5, "step " + msg, "-" * 5)
|
|
161
|
+
|
|
162
|
+
def indent(self, msg: str) -> None:
|
|
163
|
+
print(" " + msg)
|
|
164
|
+
|
|
165
|
+
return Printer()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: deltachat-rpc-client
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.158.0
|
|
4
4
|
Summary: Python client for Delta Chat core JSON-RPC interface
|
|
5
5
|
Classifier: Development Status :: 5 - Production/Stable
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -19,6 +19,7 @@ Classifier: Topic :: Communications :: Email
|
|
|
19
19
|
Requires-Python: >=3.8
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
|
+
Dynamic: license-file
|
|
22
23
|
|
|
23
24
|
# Delta Chat RPC python client
|
|
24
25
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
deltachat_rpc_client/__init__.py,sha256=L19BWnRu9TMF--jQ7e5Asgme951WGsldrTknW86KyTg,566
|
|
2
2
|
deltachat_rpc_client/_utils.py,sha256=pLOV_pxS2MRreLtq-5rnKJp-BP0m8T4LcbJ8N7Xy-D0,6304
|
|
3
|
-
deltachat_rpc_client/account.py,sha256=
|
|
3
|
+
deltachat_rpc_client/account.py,sha256=P4R_DMsVdyWu3qj4q2orwDa273Pg5Z16yivssPU6Eu4,15798
|
|
4
4
|
deltachat_rpc_client/chat.py,sha256=1pbuEBWBjZDD9qQ3U1hY5jozzx0MSs9Ybpw33reA2MU,11208
|
|
5
5
|
deltachat_rpc_client/client.py,sha256=yyXt2USkBeTsqNxtXZNNUqdsPVkqEUHYf7C-5JFmX7s,7043
|
|
6
6
|
deltachat_rpc_client/const.py,sha256=geXY_H-JHn2HLsYPAAWbwnX5LOksU7zqDZh3AOwmUpg,5577
|
|
@@ -9,11 +9,11 @@ deltachat_rpc_client/deltachat.py,sha256=c22_2GX71we6JwQ4yjP-S89mrUYPPbEb3rrPwHH
|
|
|
9
9
|
deltachat_rpc_client/events.py,sha256=qYgydsbuWYxQ1PO5ms-D8I5aHpTIiQ6Fg9p23QTvqf0,9877
|
|
10
10
|
deltachat_rpc_client/message.py,sha256=LVgQTzgaTS-24NPqSLYjgCtyz9PiTPWQgO0c_j9tIs4,3021
|
|
11
11
|
deltachat_rpc_client/py.typed,sha256=nGQ9Itq-bkXBn5Ri1JIR0oYnDNv7LDRfkowxBSSqVTM,60
|
|
12
|
-
deltachat_rpc_client/pytestplugin.py,sha256=
|
|
12
|
+
deltachat_rpc_client/pytestplugin.py,sha256=c1KSv6mc2UGzmfgr8C6_7-6WqTdE97S9QDhuukLv02Y,4900
|
|
13
13
|
deltachat_rpc_client/rpc.py,sha256=7RIdyEDwOXU0ACU0LanVqTT1RuIDci5iDr7dNEDE_tE,6554
|
|
14
|
-
deltachat_rpc_client-1.
|
|
15
|
-
deltachat_rpc_client-1.
|
|
16
|
-
deltachat_rpc_client-1.
|
|
17
|
-
deltachat_rpc_client-1.
|
|
18
|
-
deltachat_rpc_client-1.
|
|
19
|
-
deltachat_rpc_client-1.
|
|
14
|
+
deltachat_rpc_client-1.158.0.dist-info/licenses/LICENSE,sha256=Pz2eACSxkhsGfW9_iN60pgy-enjnbGTj8df8O3ebnQQ,16726
|
|
15
|
+
deltachat_rpc_client-1.158.0.dist-info/METADATA,sha256=5L0z-yQbsvJkMpuc56GD3a2y28aYpXUSggVA9pyLWMo,2175
|
|
16
|
+
deltachat_rpc_client-1.158.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
17
|
+
deltachat_rpc_client-1.158.0.dist-info/entry_points.txt,sha256=VHpX6EnKBaNj89qJWctApThnMa8suyaamfZEnQacXgc,81
|
|
18
|
+
deltachat_rpc_client-1.158.0.dist-info/top_level.txt,sha256=ePNMkY10htGrLiLydH1ITvYFM3LcTEa51HyPqJ40hDk,21
|
|
19
|
+
deltachat_rpc_client-1.158.0.dist-info/RECORD,,
|
{deltachat_rpc_client-1.157.2.dist-info → deltachat_rpc_client-1.158.0.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{deltachat_rpc_client-1.157.2.dist-info → deltachat_rpc_client-1.158.0.dist-info/licenses}/LICENSE
RENAMED
|
File without changes
|
{deltachat_rpc_client-1.157.2.dist-info → deltachat_rpc_client-1.158.0.dist-info}/top_level.txt
RENAMED
|
File without changes
|