deltachat-rpc-client 2.15.0__tar.gz → 2.17.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.
Files changed (34) hide show
  1. {deltachat_rpc_client-2.15.0/src/deltachat_rpc_client.egg-info → deltachat_rpc_client-2.17.0}/PKG-INFO +1 -1
  2. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/pyproject.toml +1 -1
  3. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client/account.py +6 -0
  4. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client/chat.py +5 -0
  5. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client/message.py +4 -0
  6. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client/pytestplugin.py +1 -3
  7. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0/src/deltachat_rpc_client.egg-info}/PKG-INFO +1 -1
  8. deltachat_rpc_client-2.17.0/tests/test_calls.py +86 -0
  9. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/tests/test_something.py +48 -0
  10. deltachat_rpc_client-2.15.0/tests/test_calls.py +0 -25
  11. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/LICENSE +0 -0
  12. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/README.md +0 -0
  13. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/setup.cfg +0 -0
  14. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client/__init__.py +0 -0
  15. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client/_utils.py +0 -0
  16. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client/client.py +0 -0
  17. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client/const.py +0 -0
  18. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client/contact.py +0 -0
  19. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client/deltachat.py +0 -0
  20. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client/events.py +0 -0
  21. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client/py.typed +0 -0
  22. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client/rpc.py +0 -0
  23. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client.egg-info/SOURCES.txt +0 -0
  24. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client.egg-info/dependency_links.txt +0 -0
  25. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client.egg-info/entry_points.txt +0 -0
  26. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/src/deltachat_rpc_client.egg-info/top_level.txt +0 -0
  27. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/tests/test_account_events.py +0 -0
  28. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/tests/test_chatlist_events.py +0 -0
  29. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/tests/test_iroh_webxdc.py +0 -0
  30. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/tests/test_key_transfer.py +0 -0
  31. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/tests/test_multidevice.py +0 -0
  32. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/tests/test_securejoin.py +0 -0
  33. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/tests/test_vcard.py +0 -0
  34. {deltachat_rpc_client-2.15.0 → deltachat_rpc_client-2.17.0}/tests/test_webxdc.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deltachat-rpc-client
3
- Version: 2.15.0
3
+ Version: 2.17.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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "deltachat-rpc-client"
7
- version = "2.15.0"
7
+ version = "2.17.0"
8
8
  description = "Python client for Delta Chat core JSON-RPC interface"
9
9
  classifiers = [
10
10
  "Development Status :: 5 - Production/Stable",
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import json
5
6
  from dataclasses import dataclass
6
7
  from typing import TYPE_CHECKING, Optional, Union
7
8
  from warnings import warn
@@ -470,3 +471,8 @@ class Account:
470
471
  def initiate_autocrypt_key_transfer(self) -> None:
471
472
  """Send Autocrypt Setup Message."""
472
473
  return self._rpc.initiate_autocrypt_key_transfer(self.id)
474
+
475
+ def ice_servers(self) -> list:
476
+ """Return ICE servers for WebRTC configuration."""
477
+ ice_servers_json = self._rpc.ice_servers(self.id)
478
+ return json.loads(ice_servers_json)
@@ -168,6 +168,11 @@ class Chat:
168
168
  msg_id = self._rpc.send_sticker(self.account.id, self.id, path)
169
169
  return Message(self.account, msg_id)
170
170
 
171
+ def resend_messages(self, messages: list[Message]) -> None:
172
+ """Resend a list of messages to this chat."""
173
+ msg_ids = [msg.id for msg in messages]
174
+ self._rpc.resend_messages(self.account.id, msg_ids)
175
+
171
176
  def forward_messages(self, messages: list[Message]) -> None:
172
177
  """Forward a list of messages to this chat."""
173
178
  msg_ids = [msg.id for msg in messages]
@@ -110,3 +110,7 @@ class Message:
110
110
  def end_call(self):
111
111
  """Ends incoming or outgoing call."""
112
112
  self._rpc.end_call(self.account.id, self.id)
113
+
114
+ def get_call_info(self) -> AttrDict:
115
+ """Return information about the call."""
116
+ return AttrDict(self._rpc.call_info(self.account.id, self.id))
@@ -28,9 +28,7 @@ class ACFactory:
28
28
 
29
29
  def get_unconfigured_account(self) -> Account:
30
30
  """Create a new unconfigured account."""
31
- account = self.deltachat.add_account()
32
- account.set_config("verified_one_on_one_chats", "1")
33
- return account
31
+ return self.deltachat.add_account()
34
32
 
35
33
  def get_unconfigured_bot(self) -> Bot:
36
34
  """Create a new unconfigured bot."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deltachat-rpc-client
3
- Version: 2.15.0
3
+ Version: 2.17.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
@@ -0,0 +1,86 @@
1
+ from deltachat_rpc_client import EventType, Message
2
+
3
+
4
+ def test_calls(acfactory) -> None:
5
+ alice, bob = acfactory.get_online_accounts(2)
6
+
7
+ place_call_info = "offer"
8
+ accept_call_info = "answer"
9
+
10
+ alice_contact_bob = alice.create_contact(bob, "Bob")
11
+ alice_chat_bob = alice_contact_bob.create_chat()
12
+ outgoing_call_message = alice_chat_bob.place_outgoing_call(place_call_info)
13
+ assert outgoing_call_message.get_call_info().state.kind == "Alerting"
14
+
15
+ incoming_call_event = bob.wait_for_event(EventType.INCOMING_CALL)
16
+ assert incoming_call_event.place_call_info == place_call_info
17
+ assert not incoming_call_event.has_video # Cannot be parsed as SDP, so false by default
18
+ incoming_call_message = Message(bob, incoming_call_event.msg_id)
19
+ assert incoming_call_message.get_call_info().state.kind == "Alerting"
20
+ assert not incoming_call_message.get_call_info().has_video
21
+
22
+ incoming_call_message.accept_incoming_call(accept_call_info)
23
+ assert incoming_call_message.get_call_info().sdp_offer == place_call_info
24
+ assert incoming_call_message.get_call_info().state.kind == "Active"
25
+ outgoing_call_accepted_event = alice.wait_for_event(EventType.OUTGOING_CALL_ACCEPTED)
26
+ assert outgoing_call_accepted_event.accept_call_info == accept_call_info
27
+ assert outgoing_call_message.get_call_info().state.kind == "Active"
28
+
29
+ outgoing_call_message.end_call()
30
+ assert outgoing_call_message.get_call_info().state.kind == "Completed"
31
+
32
+ end_call_event = bob.wait_for_event(EventType.CALL_ENDED)
33
+ assert end_call_event.msg_id == outgoing_call_message.id
34
+ assert incoming_call_message.get_call_info().state.kind == "Completed"
35
+
36
+
37
+ def test_video_call(acfactory) -> None:
38
+ # Example from <https://datatracker.ietf.org/doc/rfc9143/>
39
+ # with `s= ` replaced with `s=-`.
40
+ #
41
+ # `s=` cannot be empty according to RFC 3264,
42
+ # so it is more clear as `s=-`.
43
+ place_call_info = """v=0\r
44
+ o=alice 2890844526 2890844526 IN IP6 2001:db8::3\r
45
+ s=-\r
46
+ c=IN IP6 2001:db8::3\r
47
+ t=0 0\r
48
+ a=group:BUNDLE foo bar\r
49
+ \r
50
+ m=audio 10000 RTP/AVP 0 8 97\r
51
+ b=AS:200\r
52
+ a=mid:foo\r
53
+ a=rtcp-mux\r
54
+ a=rtpmap:0 PCMU/8000\r
55
+ a=rtpmap:8 PCMA/8000\r
56
+ a=rtpmap:97 iLBC/8000\r
57
+ a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid\r
58
+ \r
59
+ m=video 10002 RTP/AVP 31 32\r
60
+ b=AS:1000\r
61
+ a=mid:bar\r
62
+ a=rtcp-mux\r
63
+ a=rtpmap:31 H261/90000\r
64
+ a=rtpmap:32 MPV/90000\r
65
+ a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid\r
66
+ """
67
+
68
+ alice, bob = acfactory.get_online_accounts(2)
69
+
70
+ alice_contact_bob = alice.create_contact(bob, "Bob")
71
+ alice_chat_bob = alice_contact_bob.create_chat()
72
+ alice_chat_bob.place_outgoing_call(place_call_info)
73
+
74
+ incoming_call_event = bob.wait_for_event(EventType.INCOMING_CALL)
75
+ assert incoming_call_event.place_call_info == place_call_info
76
+ assert incoming_call_event.has_video
77
+
78
+ incoming_call_message = Message(bob, incoming_call_event.msg_id)
79
+ assert incoming_call_message.get_call_info().has_video
80
+
81
+
82
+ def test_ice_servers(acfactory) -> None:
83
+ alice = acfactory.get_online_account()
84
+
85
+ ice_servers = alice.ice_servers()
86
+ assert len(ice_servers) == 1
@@ -252,6 +252,7 @@ def test_chat(acfactory) -> None:
252
252
  bob_chat_alice.get_encryption_info()
253
253
 
254
254
  group = alice.create_group("test group")
255
+ to_resend = group.send_text("will be resent")
255
256
  group.add_contact(alice_contact_bob)
256
257
  group.get_qr_code()
257
258
 
@@ -263,6 +264,7 @@ def test_chat(acfactory) -> None:
263
264
 
264
265
  msg = group.send_message(text="hi")
265
266
  assert (msg.get_snapshot()).text == "hi"
267
+ group.resend_messages([to_resend])
266
268
  group.forward_messages([msg])
267
269
 
268
270
  group.set_draft(text="test draft")
@@ -329,6 +331,52 @@ def test_message(acfactory) -> None:
329
331
  assert reactions == snapshot.reactions
330
332
 
331
333
 
334
+ def test_receive_imf_failure(acfactory) -> None:
335
+ alice, bob = acfactory.get_online_accounts(2)
336
+ alice_contact_bob = alice.create_contact(bob, "Bob")
337
+ alice_chat_bob = alice_contact_bob.create_chat()
338
+
339
+ bob.set_config("fail_on_receiving_full_msg", "1")
340
+ alice_chat_bob.send_text("Hello!")
341
+ event = bob.wait_for_incoming_msg_event()
342
+ chat_id = event.chat_id
343
+ msg_id = event.msg_id
344
+ message = bob.get_message_by_id(msg_id)
345
+ snapshot = message.get_snapshot()
346
+ assert snapshot.chat_id == chat_id
347
+ assert snapshot.download_state == DownloadState.AVAILABLE
348
+ assert snapshot.error is not None
349
+ assert snapshot.show_padlock
350
+
351
+ # The failed message doesn't break the IMAP loop.
352
+ bob.set_config("fail_on_receiving_full_msg", "0")
353
+ alice_chat_bob.send_text("Hello again!")
354
+ event = bob.wait_for_incoming_msg_event()
355
+ assert event.chat_id == chat_id
356
+ msg_id = event.msg_id
357
+ message1 = bob.get_message_by_id(msg_id)
358
+ snapshot = message1.get_snapshot()
359
+ assert snapshot.chat_id == chat_id
360
+ assert snapshot.download_state == DownloadState.DONE
361
+ assert snapshot.error is None
362
+
363
+ # The failed message can be re-downloaded later.
364
+ bob._rpc.download_full_message(bob.id, message.id)
365
+ event = bob.wait_for_event(EventType.MSGS_CHANGED)
366
+ message = bob.get_message_by_id(event.msg_id)
367
+ snapshot = message.get_snapshot()
368
+ assert snapshot.download_state == DownloadState.IN_PROGRESS
369
+ event = bob.wait_for_event(EventType.MSGS_CHANGED)
370
+ assert event.chat_id == chat_id
371
+ msg_id = event.msg_id
372
+ message = bob.get_message_by_id(msg_id)
373
+ snapshot = message.get_snapshot()
374
+ assert snapshot.chat_id == chat_id
375
+ assert snapshot.download_state == DownloadState.DONE
376
+ assert snapshot.error is None
377
+ assert snapshot.text == "Hello!"
378
+
379
+
332
380
  def test_selfavatar_sync(acfactory, data, log) -> None:
333
381
  alice = acfactory.get_online_account()
334
382
 
@@ -1,25 +0,0 @@
1
- from deltachat_rpc_client import EventType, Message
2
-
3
-
4
- def test_calls(acfactory) -> None:
5
- alice, bob = acfactory.get_online_accounts(2)
6
-
7
- place_call_info = "offer"
8
- accept_call_info = "answer"
9
-
10
- alice_contact_bob = alice.create_contact(bob, "Bob")
11
- alice_chat_bob = alice_contact_bob.create_chat()
12
- outgoing_call_message = alice_chat_bob.place_outgoing_call(place_call_info)
13
-
14
- incoming_call_event = bob.wait_for_event(EventType.INCOMING_CALL)
15
- assert incoming_call_event.place_call_info == place_call_info
16
- incoming_call_message = Message(bob, incoming_call_event.msg_id)
17
-
18
- incoming_call_message.accept_incoming_call(accept_call_info)
19
- outgoing_call_accepted_event = alice.wait_for_event(EventType.OUTGOING_CALL_ACCEPTED)
20
- assert outgoing_call_accepted_event.accept_call_info == accept_call_info
21
-
22
- outgoing_call_message.end_call()
23
-
24
- end_call_event = bob.wait_for_event(EventType.CALL_ENDED)
25
- assert end_call_event.msg_id == outgoing_call_message.id