isamert / scli

a simple terminal user interface for signal messenger (using signal-cli)
GNU General Public License v3.0
439 stars 40 forks source link

Crash with `KeyError: contactStore` on startup #125

Closed cycneuramus closed 3 years ago

cycneuramus commented 3 years ago

Hi all. Yesterday I updated to signal-cli v.0.8.2, and as of today, scli is crashing on start:

Traceback (most recent call last):
  File "/usr/bin/scli", line 4335, in <module>
    main()
  File "/usr/bin/scli", line 4320, in main
    coord = Coordinate()
  File "/usr/bin/scli", line 3694, in __init__
    self._contacts = Contacts(sigdata)
  File "/usr/bin/scli", line 997, in __init__
    self.reload()
  File "/usr/bin/scli", line 1000, in reload
    indivs_dicts, groups_dicts = self._sigdata.parse_data_file()
  File "/usr/bin/scli", line 882, in parse_data_file
    for cont in self._data['contactStore']['contacts']:
KeyError: 'contactStore'

I tried clearing out all data for both signal-cli and scli and then re-linking, with the same result.

I'd be grateful for your assistance here. Please let me know if you need additional information.

taimon commented 3 years ago

Looks like the contacts API changed.

There is no longer a contactStore section in the data file. It looks like the contacts moved to the "recipients-store" file.

/Edit: Preliminary fix for me: deleted, see below for update Not properly tested yet and not sure about any other changes to contacts object.

/Edit2: Still needs some work. The number is not part of the contact object anymore, so some other functions need small adjustments or it needs to be added when creating the contacts_map. I'm currently running a 2 months old version of scli, so the lines need to be adjusted for latest version.

--- scli    2021-03-12 17:19:28.000000000 +0100
+++ scli    2021-05-13 00:46:53.252943173 +0200
@@ -1257,7 +1257,10 @@
         with open(self._path) as f:
             self._data = json.load(f)

-        self.contacts = self._data['contactStore']['contacts']
+        with open(os.path.join(self._path + ".d", "recipients-store")) as f:
+            self.contacts = json.load(f)['recipients']
+
+        #self.contacts = self._data['contactStore']['contacts']
         self.groups = []
         for g in self._data["groupStore"]['groups']:
             if is_group_v2(g):
@@ -1266,7 +1269,7 @@
             if g.get('archived') or not g.get('name'):
                 continue
             self.groups.append(g)
-        self.contacts_map = {c['number']: c for c in self.contacts}
+        self.contacts_map = {c['number']: dict(number=c['number'], **c['contact']) for c in self.contacts if c['contact']}
         self.contacts_map.update({g['groupId']: g for g in self.groups})
         self._set_v2_groups_info_async_watch()

Still not the best solution, because it ignores entries without 'contact' info. But it might help until a proper fix is done.

exquo commented 3 years ago

Indeed, the data storage schema has changed in the new version of signal-cli.

I will write incorporate the changes into scli's parser in a bit.

taimon commented 3 years ago

@exquo: Thanks for the quick and backwards-compatible fix.