deltachat-rpc-client 2.28.0__tar.gz → 2.29.0__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-2.28.0/src/deltachat_rpc_client.egg-info → deltachat_rpc_client-2.29.0}/PKG-INFO +3 -5
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/pyproject.toml +4 -6
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/message.py +4 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/rpc.py +23 -48
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0/src/deltachat_rpc_client.egg-info}/PKG-INFO +3 -5
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client.egg-info/SOURCES.txt +1 -0
- deltachat_rpc_client-2.29.0/tests/test_rpc_virtual.py +20 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/tests/test_something.py +20 -11
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/LICENSE +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/README.md +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/setup.cfg +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/__init__.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/_utils.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/account.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/chat.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/client.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/const.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/contact.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/deltachat.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/events.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/py.typed +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/pytestplugin.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client.egg-info/dependency_links.txt +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client.egg-info/entry_points.txt +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client.egg-info/top_level.txt +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/tests/test_account_events.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/tests/test_calls.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/tests/test_chatlist_events.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/tests/test_folders.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/tests/test_iroh_webxdc.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/tests/test_key_transfer.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/tests/test_multidevice.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/tests/test_multitransport.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/tests/test_securejoin.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/tests/test_vcard.py +0 -0
- {deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/tests/test_webxdc.py +0 -0
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deltachat-rpc-client
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.29.0
|
|
4
4
|
Summary: Python client for Delta Chat core JSON-RPC interface
|
|
5
|
+
License-Expression: MPL-2.0
|
|
5
6
|
Classifier: Development Status :: 5 - Production/Stable
|
|
6
7
|
Classifier: Intended Audience :: Developers
|
|
7
|
-
Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
|
|
8
8
|
Classifier: Operating System :: POSIX :: Linux
|
|
9
9
|
Classifier: Operating System :: MacOS :: MacOS X
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
13
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
14
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -17,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
17
15
|
Classifier: Programming Language :: Python :: 3.14
|
|
18
16
|
Classifier: Topic :: Communications :: Chat
|
|
19
17
|
Classifier: Topic :: Communications :: Email
|
|
20
|
-
Requires-Python: >=3.
|
|
18
|
+
Requires-Python: >=3.10
|
|
21
19
|
Description-Content-Type: text/markdown
|
|
22
20
|
License-File: LICENSE
|
|
23
21
|
Dynamic: license-file
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools>=
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "deltachat-rpc-client"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.29.0"
|
|
8
|
+
license = "MPL-2.0"
|
|
8
9
|
description = "Python client for Delta Chat core JSON-RPC interface"
|
|
9
10
|
classifiers = [
|
|
10
11
|
"Development Status :: 5 - Production/Stable",
|
|
11
12
|
"Intended Audience :: Developers",
|
|
12
|
-
"License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)",
|
|
13
13
|
"Operating System :: POSIX :: Linux",
|
|
14
14
|
"Operating System :: MacOS :: MacOS X",
|
|
15
15
|
"Programming Language :: Python :: 3",
|
|
16
|
-
"Programming Language :: Python :: 3.8",
|
|
17
|
-
"Programming Language :: Python :: 3.9",
|
|
18
16
|
"Programming Language :: Python :: 3.10",
|
|
19
17
|
"Programming Language :: Python :: 3.11",
|
|
20
18
|
"Programming Language :: Python :: 3.12",
|
|
@@ -24,7 +22,7 @@ classifiers = [
|
|
|
24
22
|
"Topic :: Communications :: Email"
|
|
25
23
|
]
|
|
26
24
|
readme = "README.md"
|
|
27
|
-
requires-python = ">=3.
|
|
25
|
+
requires-python = ">=3.10"
|
|
28
26
|
|
|
29
27
|
[tool.setuptools.package-data]
|
|
30
28
|
deltachat_rpc_client = [
|
{deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/message.py
RENAMED
|
@@ -60,6 +60,10 @@ class Message:
|
|
|
60
60
|
"""Mark the message as seen."""
|
|
61
61
|
self._rpc.markseen_msgs(self.account.id, [self.id])
|
|
62
62
|
|
|
63
|
+
def exists(self) -> bool:
|
|
64
|
+
"""Return True if the message exists."""
|
|
65
|
+
return bool(self._rpc.get_existing_msg_ids(self.account.id, [self.id]))
|
|
66
|
+
|
|
63
67
|
def continue_autocrypt_key_transfer(self, setup_code: str) -> None:
|
|
64
68
|
"""Continue the Autocrypt Setup Message key transfer.
|
|
65
69
|
|
|
@@ -9,7 +9,7 @@ import os
|
|
|
9
9
|
import subprocess
|
|
10
10
|
import sys
|
|
11
11
|
from queue import Empty, Queue
|
|
12
|
-
from threading import
|
|
12
|
+
from threading import Thread
|
|
13
13
|
from typing import Any, Iterator, Optional
|
|
14
14
|
|
|
15
15
|
|
|
@@ -17,25 +17,6 @@ class JsonRpcError(Exception):
|
|
|
17
17
|
"""JSON-RPC error."""
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
class RpcFuture:
|
|
21
|
-
"""RPC future waiting for RPC call result."""
|
|
22
|
-
|
|
23
|
-
def __init__(self, rpc: "Rpc", request_id: int, event: Event):
|
|
24
|
-
self.rpc = rpc
|
|
25
|
-
self.request_id = request_id
|
|
26
|
-
self.event = event
|
|
27
|
-
|
|
28
|
-
def __call__(self):
|
|
29
|
-
"""Wait for the future to return the result."""
|
|
30
|
-
self.event.wait()
|
|
31
|
-
response = self.rpc.request_results.pop(self.request_id)
|
|
32
|
-
if "error" in response:
|
|
33
|
-
raise JsonRpcError(response["error"])
|
|
34
|
-
if "result" in response:
|
|
35
|
-
return response["result"]
|
|
36
|
-
return None
|
|
37
|
-
|
|
38
|
-
|
|
39
20
|
class RpcMethod:
|
|
40
21
|
"""RPC method."""
|
|
41
22
|
|
|
@@ -57,17 +38,23 @@ class RpcMethod:
|
|
|
57
38
|
"params": args,
|
|
58
39
|
"id": request_id,
|
|
59
40
|
}
|
|
60
|
-
|
|
61
|
-
self.rpc.request_events[request_id] = event
|
|
41
|
+
self.rpc.request_results[request_id] = queue = Queue()
|
|
62
42
|
self.rpc.request_queue.put(request)
|
|
63
43
|
|
|
64
|
-
|
|
44
|
+
def rpc_future():
|
|
45
|
+
"""Wait for the request to receive a result."""
|
|
46
|
+
response = queue.get()
|
|
47
|
+
if "error" in response:
|
|
48
|
+
raise JsonRpcError(response["error"])
|
|
49
|
+
return response.get("result", None)
|
|
50
|
+
|
|
51
|
+
return rpc_future
|
|
65
52
|
|
|
66
53
|
|
|
67
54
|
class Rpc:
|
|
68
55
|
"""RPC client."""
|
|
69
56
|
|
|
70
|
-
def __init__(self, accounts_dir: Optional[str] = None, **kwargs):
|
|
57
|
+
def __init__(self, accounts_dir: Optional[str] = None, rpc_server_path="deltachat-rpc-server", **kwargs):
|
|
71
58
|
"""Initialize RPC client.
|
|
72
59
|
|
|
73
60
|
The given arguments will be passed to subprocess.Popen().
|
|
@@ -79,13 +66,12 @@ class Rpc:
|
|
|
79
66
|
}
|
|
80
67
|
|
|
81
68
|
self._kwargs = kwargs
|
|
69
|
+
self.rpc_server_path = rpc_server_path
|
|
82
70
|
self.process: subprocess.Popen
|
|
83
71
|
self.id_iterator: Iterator[int]
|
|
84
72
|
self.event_queues: dict[int, Queue]
|
|
85
|
-
# Map from request ID to
|
|
86
|
-
self.
|
|
87
|
-
# Map from request ID to the result.
|
|
88
|
-
self.request_results: dict[int, Any]
|
|
73
|
+
# Map from request ID to a Queue which provides a single result
|
|
74
|
+
self.request_results: dict[int, Queue]
|
|
89
75
|
self.request_queue: Queue[Any]
|
|
90
76
|
self.closing: bool
|
|
91
77
|
self.reader_thread: Thread
|
|
@@ -94,27 +80,18 @@ class Rpc:
|
|
|
94
80
|
|
|
95
81
|
def start(self) -> None:
|
|
96
82
|
"""Start RPC server subprocess."""
|
|
83
|
+
popen_kwargs = {"stdin": subprocess.PIPE, "stdout": subprocess.PIPE}
|
|
97
84
|
if sys.version_info >= (3, 11):
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
stdin=subprocess.PIPE,
|
|
101
|
-
stdout=subprocess.PIPE,
|
|
102
|
-
# Prevent subprocess from capturing SIGINT.
|
|
103
|
-
process_group=0,
|
|
104
|
-
**self._kwargs,
|
|
105
|
-
)
|
|
85
|
+
# Prevent subprocess from capturing SIGINT.
|
|
86
|
+
popen_kwargs["process_group"] = 0
|
|
106
87
|
else:
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
preexec_fn=os.setpgrp, # noqa: PLW1509
|
|
113
|
-
**self._kwargs,
|
|
114
|
-
)
|
|
88
|
+
# `process_group` is not supported before Python 3.11.
|
|
89
|
+
popen_kwargs["preexec_fn"] = os.setpgrp # noqa: PLW1509
|
|
90
|
+
|
|
91
|
+
popen_kwargs.update(self._kwargs)
|
|
92
|
+
self.process = subprocess.Popen(self.rpc_server_path, **popen_kwargs)
|
|
115
93
|
self.id_iterator = itertools.count(start=1)
|
|
116
94
|
self.event_queues = {}
|
|
117
|
-
self.request_events = {}
|
|
118
95
|
self.request_results = {}
|
|
119
96
|
self.request_queue = Queue()
|
|
120
97
|
self.closing = False
|
|
@@ -149,9 +126,7 @@ class Rpc:
|
|
|
149
126
|
response = json.loads(line)
|
|
150
127
|
if "id" in response:
|
|
151
128
|
response_id = response["id"]
|
|
152
|
-
|
|
153
|
-
self.request_results[response_id] = response
|
|
154
|
-
event.set()
|
|
129
|
+
self.request_results.pop(response_id).put(response)
|
|
155
130
|
else:
|
|
156
131
|
logging.warning("Got a response without ID: %s", response)
|
|
157
132
|
except Exception:
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deltachat-rpc-client
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.29.0
|
|
4
4
|
Summary: Python client for Delta Chat core JSON-RPC interface
|
|
5
|
+
License-Expression: MPL-2.0
|
|
5
6
|
Classifier: Development Status :: 5 - Production/Stable
|
|
6
7
|
Classifier: Intended Audience :: Developers
|
|
7
|
-
Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
|
|
8
8
|
Classifier: Operating System :: POSIX :: Linux
|
|
9
9
|
Classifier: Operating System :: MacOS :: MacOS X
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
13
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
14
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -17,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
17
15
|
Classifier: Programming Language :: Python :: 3.14
|
|
18
16
|
Classifier: Topic :: Communications :: Chat
|
|
19
17
|
Classifier: Topic :: Communications :: Email
|
|
20
|
-
Requires-Python: >=3.
|
|
18
|
+
Requires-Python: >=3.10
|
|
21
19
|
Description-Content-Type: text/markdown
|
|
22
20
|
License-File: LICENSE
|
|
23
21
|
Dynamic: license-file
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import sys
|
|
3
|
+
from platform import system # noqa
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from deltachat_rpc_client import DeltaChat, Rpc
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.mark.skipif("system() == 'Windows'")
|
|
11
|
+
def test_install_venv_and_use_other_core(tmp_path):
|
|
12
|
+
venv = tmp_path.joinpath("venv1")
|
|
13
|
+
subprocess.check_call([sys.executable, "-m", "venv", venv])
|
|
14
|
+
python = venv / "bin" / "python"
|
|
15
|
+
subprocess.check_call([python, "-m", "pip", "install", "deltachat-rpc-server==2.20.0"])
|
|
16
|
+
rpc = Rpc(accounts_dir=tmp_path.joinpath("accounts"), rpc_server_path=venv.joinpath("bin", "deltachat-rpc-server"))
|
|
17
|
+
|
|
18
|
+
with rpc:
|
|
19
|
+
dc = DeltaChat(rpc)
|
|
20
|
+
assert dc.rpc.get_system_info()["deltachat_core_version"] == "v2.20.0"
|
|
@@ -661,8 +661,6 @@ def test_download_limit_chat_assignment(acfactory, tmp_path, n_accounts):
|
|
|
661
661
|
contact = alice.create_contact(account)
|
|
662
662
|
alice_group.add_contact(contact)
|
|
663
663
|
|
|
664
|
-
if n_accounts == 2:
|
|
665
|
-
bob_chat_alice = bob.create_chat(alice)
|
|
666
664
|
bob.set_config("download_limit", str(download_limit))
|
|
667
665
|
|
|
668
666
|
alice_group.send_text("hi")
|
|
@@ -678,15 +676,7 @@ def test_download_limit_chat_assignment(acfactory, tmp_path, n_accounts):
|
|
|
678
676
|
alice_group.send_file(str(path))
|
|
679
677
|
snapshot = bob.wait_for_incoming_msg().get_snapshot()
|
|
680
678
|
assert snapshot.download_state == DownloadState.AVAILABLE
|
|
681
|
-
|
|
682
|
-
assert snapshot.chat == bob_group
|
|
683
|
-
else:
|
|
684
|
-
# Group contains only Alice and Bob,
|
|
685
|
-
# so partially downloaded messages are
|
|
686
|
-
# hard to distinguish from private replies to group messages.
|
|
687
|
-
#
|
|
688
|
-
# Message may be a private reply, so we assign it to 1:1 chat with Alice.
|
|
689
|
-
assert snapshot.chat == bob_chat_alice
|
|
679
|
+
assert snapshot.chat == bob_group
|
|
690
680
|
|
|
691
681
|
|
|
692
682
|
def test_markseen_contact_request(acfactory):
|
|
@@ -1003,3 +993,22 @@ def test_background_fetch(acfactory, dc):
|
|
|
1003
993
|
snapshot = messages[-1].get_snapshot()
|
|
1004
994
|
if snapshot.text == "Hello again!":
|
|
1005
995
|
break
|
|
996
|
+
|
|
997
|
+
|
|
998
|
+
def test_message_exists(acfactory):
|
|
999
|
+
ac1, ac2 = acfactory.get_online_accounts(2)
|
|
1000
|
+
chat = ac1.create_chat(ac2)
|
|
1001
|
+
message1 = chat.send_text("Hello!")
|
|
1002
|
+
message2 = chat.send_text("Hello again!")
|
|
1003
|
+
assert message1.exists()
|
|
1004
|
+
assert message2.exists()
|
|
1005
|
+
|
|
1006
|
+
ac1.delete_messages([message1])
|
|
1007
|
+
assert not message1.exists()
|
|
1008
|
+
assert message2.exists()
|
|
1009
|
+
|
|
1010
|
+
# There is no error when checking if
|
|
1011
|
+
# the message exists for deleted account.
|
|
1012
|
+
ac1.remove()
|
|
1013
|
+
assert not message1.exists()
|
|
1014
|
+
assert not message2.exists()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/__init__.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/_utils.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/account.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/chat.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/client.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/const.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/contact.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/deltachat.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/events.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/py.typed
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.28.0 → deltachat_rpc_client-2.29.0}/src/deltachat_rpc_client/pytestplugin.py
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
|
|
File without changes
|