Parse and match vCard properties that use grouping prefixes (e.g. item1.TEL) by extracting the property name correctly.
Regression caused by the removal of the vobject dependency.
In `Timing.format_timestamp`, if `self.timezone_offset` is `None` (which is explicitly allowed by the `Optional[int]` type hint), it instantiates `TimeZone(None)`.
When `datetime.fromtimestamp()` calls the `utcoffset()` method on this timezone object, it executes `timedelta(hours=self.offset)`, which evaluates to `timedelta(hours=None)`. This raises a `TypeError: unsupported type for timedelta hours component: NoneType`, causing the application to crash during export.
Affected files: data_model.py
Signed-off-by: Tang Vu <vuminhtang2212@gmail.com>
- Add poll message decoding for iOS (ZMESSAGETYPE 46) using raw protobuf
parsing of ZWAMESSAGEINFO.ZRECEIPTINFO blobs (no external dependency).
Polls render with vote tallies and voter names in the HTML export.
- Fix iOS contact name resolution: pull ZFULLNAME from address book,
resolve LID-based group members, fall back to ZWAPROFILEPUSHNAME,
and avoid overwriting real names with phone numbers.
- Fix typo: 'expoter' -> 'exporter' in android_crypt.py and __main__.py.
- Add poll field to Message data model and update test fixtures.
I realized the `jid_map` table might be missing after reviewing @lifnej's work in ee7db80. This fix adds use the preflight check result for the table before querying it.
I plan to apply this same pattern to other sections where `jid_map` is used.
WhatsApp doesn't show when a reaction was made, and I don't want to mess with a popup in the HTML yet. Let’s just fetch the data for now. It might come in handy later.
Credit to @tlcameron3 from #79
Refactored the brute-force offset search in `_decrypt_crypt14` to use `ProcessPoolExecutor` for better parallelism and performance. Improved progress reporting and clean shutdown on success or interruption.