deltachat-rpc-client 1.156.2__tar.gz → 1.157.2__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 (31) hide show
  1. {deltachat_rpc_client-1.156.2/src/deltachat_rpc_client.egg-info → deltachat_rpc_client-1.157.2}/PKG-INFO +1 -1
  2. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/pyproject.toml +1 -1
  3. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client/account.py +47 -2
  4. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client/contact.py +1 -1
  5. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2/src/deltachat_rpc_client.egg-info}/PKG-INFO +1 -1
  6. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/tests/test_chatlist_events.py +1 -5
  7. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/tests/test_securejoin.py +2 -5
  8. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/tests/test_something.py +29 -10
  9. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/LICENSE +0 -0
  10. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/README.md +0 -0
  11. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/setup.cfg +0 -0
  12. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client/__init__.py +0 -0
  13. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client/_utils.py +0 -0
  14. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client/chat.py +0 -0
  15. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client/client.py +0 -0
  16. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client/const.py +0 -0
  17. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client/deltachat.py +0 -0
  18. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client/events.py +0 -0
  19. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client/message.py +0 -0
  20. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client/py.typed +0 -0
  21. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client/pytestplugin.py +0 -0
  22. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client/rpc.py +0 -0
  23. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client.egg-info/SOURCES.txt +0 -0
  24. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client.egg-info/dependency_links.txt +0 -0
  25. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client.egg-info/entry_points.txt +0 -0
  26. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/src/deltachat_rpc_client.egg-info/top_level.txt +0 -0
  27. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/tests/test_account_events.py +0 -0
  28. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/tests/test_iroh_webxdc.py +0 -0
  29. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/tests/test_key_transfer.py +0 -0
  30. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/tests/test_vcard.py +0 -0
  31. {deltachat_rpc_client-1.156.2 → deltachat_rpc_client-1.157.2}/tests/test_webxdc.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: deltachat-rpc-client
3
- Version: 1.156.2
3
+ Version: 1.157.2
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 = "1.156.2"
7
+ version = "1.157.2"
8
8
  description = "Python client for Delta Chat core JSON-RPC interface"
9
9
  classifiers = [
10
10
  "Development Status :: 5 - Production/Stable",
@@ -1,6 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
+ from pathlib import Path
5
+ from tempfile import TemporaryDirectory
4
6
  from typing import TYPE_CHECKING, Optional, Union
5
7
  from warnings import warn
6
8
 
@@ -38,6 +40,16 @@ class Account:
38
40
  """Remove the account."""
39
41
  self._rpc.remove_account(self.id)
40
42
 
43
+ def clone(self) -> "Account":
44
+ """Clone given account."""
45
+ with TemporaryDirectory() as tmp_dir:
46
+ tmp_path = Path(tmp_dir)
47
+ self.export_backup(tmp_path)
48
+ files = list(tmp_path.glob("*.tar"))
49
+ new_account = self.manager.add_account()
50
+ new_account.import_backup(files[0])
51
+ return new_account
52
+
41
53
  def start_io(self) -> None:
42
54
  """Start the account I/O."""
43
55
  self._rpc.start_io(self.id)
@@ -83,6 +95,10 @@ class Account:
83
95
  return self.get_config("selfavatar")
84
96
 
85
97
  def check_qr(self, qr):
98
+ """Parse QR code contents.
99
+
100
+ This function takes the raw text scanned
101
+ and checks what can be done with it."""
86
102
  return self._rpc.check_qr(self.id, qr)
87
103
 
88
104
  def set_config_from_qr(self, qr: str):
@@ -118,11 +134,28 @@ class Account:
118
134
  obj = obj.get_snapshot().address
119
135
  return Contact(self, self._rpc.create_contact(self.id, obj, name))
120
136
 
137
+ def make_vcard(self, contacts: list[Contact]) -> str:
138
+ """Create vCard with the given contacts."""
139
+ assert all(contact.account == self for contact in contacts)
140
+ contact_ids = [contact.id for contact in contacts]
141
+ return self._rpc.make_vcard(self.id, contact_ids)
142
+
143
+ def import_vcard(self, vcard: str) -> list[Contact]:
144
+ """Import vCard.
145
+
146
+ Return created or modified contacts in the order they appear in vCard."""
147
+ contact_ids = self._rpc.import_vcard_contents(self.id, vcard)
148
+ return [Contact(self, contact_id) for contact_id in contact_ids]
149
+
121
150
  def create_chat(self, account: "Account") -> Chat:
122
- addr = account.get_config("addr")
123
- contact = self.create_contact(addr)
151
+ vcard = account.self_contact.make_vcard()
152
+ [contact] = self.import_vcard(vcard)
124
153
  return contact.create_chat()
125
154
 
155
+ def get_device_chat(self) -> Chat:
156
+ """Return device chat."""
157
+ return self.device_contact.create_chat()
158
+
126
159
  def get_contact_by_id(self, contact_id: int) -> Contact:
127
160
  """Return Contact instance for the given contact ID."""
128
161
  return Contact(self, contact_id)
@@ -183,6 +216,11 @@ class Account:
183
216
  """This account's identity as a Contact."""
184
217
  return Contact(self, SpecialContactId.SELF)
185
218
 
219
+ @property
220
+ def device_contact(self) -> Chat:
221
+ """This account's device contact."""
222
+ return Contact(self, SpecialContactId.DEVICE)
223
+
186
224
  def get_chatlist(
187
225
  self,
188
226
  query: Optional[str] = None,
@@ -308,6 +346,13 @@ class Account:
308
346
  if event.kind == EventType.MSGS_CHANGED:
309
347
  return event
310
348
 
349
+ def wait_for_msgs_noticed_event(self):
350
+ """Wait for messages noticed event and return it."""
351
+ while True:
352
+ event = self.wait_for_event()
353
+ if event.kind == EventType.MSGS_NOTICED:
354
+ return event
355
+
311
356
  def wait_for_incoming_msg(self):
312
357
  """Wait for incoming message and return it.
313
358
 
@@ -66,4 +66,4 @@ class Contact:
66
66
  )
67
67
 
68
68
  def make_vcard(self) -> str:
69
- return self._rpc.make_vcard(self.account.id, [self.id])
69
+ return self.account.make_vcard([self])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: deltachat-rpc-client
3
- Version: 1.156.2
3
+ Version: 1.157.2
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
@@ -157,11 +157,7 @@ def get_multi_account_test_setup(acfactory: ACFactory) -> [Account, Account, Acc
157
157
 
158
158
  bob.wait_for_incoming_msg_event()
159
159
 
160
- alice_second_device: Account = acfactory.get_unconfigured_account()
161
-
162
- alice._rpc.provide_backup.future(alice.id)
163
- backup_code = alice._rpc.get_backup_qr(alice.id)
164
- alice_second_device._rpc.get_backup(alice_second_device.id, backup_code)
160
+ alice_second_device = alice.clone()
165
161
  alice_second_device.start_io()
166
162
  alice.clear_all_events()
167
163
  alice_second_device.clear_all_events()
@@ -60,15 +60,12 @@ def test_qr_setup_contact_svg(acfactory) -> None:
60
60
 
61
61
 
62
62
  @pytest.mark.parametrize("protect", [True, False])
63
- def test_qr_securejoin(acfactory, protect, tmp_path):
63
+ def test_qr_securejoin(acfactory, protect):
64
64
  alice, bob, fiona = acfactory.get_online_accounts(3)
65
65
 
66
66
  # Setup second device for Alice
67
67
  # to test observing securejoin protocol.
68
- alice.export_backup(tmp_path)
69
- files = list(tmp_path.glob("*.tar"))
70
- alice2 = acfactory.get_unconfigured_account()
71
- alice2.import_backup(files[0])
68
+ alice2 = alice.clone()
72
69
 
73
70
  logging.info("Alice creates a group")
74
71
  alice_chat = alice.create_group("Group", protect=protect)
@@ -287,12 +287,9 @@ def test_message(acfactory) -> None:
287
287
  assert reactions == snapshot.reactions
288
288
 
289
289
 
290
- def test_reaction_seen_on_another_dev(acfactory, tmp_path) -> None:
290
+ def test_reaction_seen_on_another_dev(acfactory) -> None:
291
291
  alice, bob = acfactory.get_online_accounts(2)
292
- alice.export_backup(tmp_path)
293
- files = list(tmp_path.glob("*.tar"))
294
- alice2 = acfactory.get_unconfigured_account()
295
- alice2.import_backup(files[0])
292
+ alice2 = alice.clone()
296
293
  alice2.start_io()
297
294
 
298
295
  bob_addr = bob.get_config("addr")
@@ -661,7 +658,7 @@ def test_download_limit_chat_assignment(acfactory, tmp_path, n_accounts):
661
658
  assert snapshot.chat == bob_chat_alice
662
659
 
663
660
 
664
- def test_markseen_contact_request(acfactory, tmp_path):
661
+ def test_markseen_contact_request(acfactory):
665
662
  """
666
663
  Test that seen status is synchronized for contact request messages
667
664
  even though read receipt is not sent.
@@ -669,10 +666,7 @@ def test_markseen_contact_request(acfactory, tmp_path):
669
666
  alice, bob = acfactory.get_online_accounts(2)
670
667
 
671
668
  # Bob sets up a second device.
672
- bob.export_backup(tmp_path)
673
- files = list(tmp_path.glob("*.tar"))
674
- bob2 = acfactory.get_unconfigured_account()
675
- bob2.import_backup(files[0])
669
+ bob2 = bob.clone()
676
670
  bob2.start_io()
677
671
 
678
672
  alice_chat_bob = alice.create_chat(bob)
@@ -716,3 +710,28 @@ def test_configured_imap_certificate_checks(acfactory):
716
710
  # Core 1.142.4, 1.142.5 and 1.142.6 saved this value due to bug.
717
711
  # This test is a regression test to prevent this happening again.
718
712
  assert configured_certificate_checks != "0"
713
+
714
+
715
+ def test_no_old_msg_is_fresh(acfactory):
716
+ ac1, ac2 = acfactory.get_online_accounts(2)
717
+ ac1_clone = ac1.clone()
718
+ ac1_clone.start_io()
719
+
720
+ ac1.create_chat(ac2)
721
+ ac1_clone_chat = ac1_clone.create_chat(ac2)
722
+
723
+ ac1.get_device_chat().mark_noticed()
724
+
725
+ logging.info("Send a first message from ac2 to ac1 and check that it's 'fresh'")
726
+ first_msg = ac2.create_chat(ac1).send_text("Hi")
727
+ ac1.wait_for_incoming_msg_event()
728
+ assert ac1.create_chat(ac2).get_fresh_message_count() == 1
729
+ assert len(list(ac1.get_fresh_messages())) == 1
730
+
731
+ logging.info("Send a message from ac1_clone to ac2 and check that ac1 marks the first message as 'noticed'")
732
+ ac1_clone_chat.send_text("Hi back")
733
+ ev = ac1.wait_for_msgs_noticed_event()
734
+
735
+ assert ev.chat_id == first_msg.get_snapshot().chat_id
736
+ assert ac1.create_chat(ac2).get_fresh_message_count() == 0
737
+ assert len(list(ac1.get_fresh_messages())) == 0