Feature/android threema export#25
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new importer pipeline for encrypted Threema Android “data-backup” ZIPs (v27) and wires it into the existing export orchestration, UI surfaces (Windows GUI + CLI), rendering, and traceability outputs, backed by synthetic fixtures and regression tests.
Changes:
- Introduces
chat_export.threema_android(archive access, identity decryption, attachment handling, normalization, and importer). - Extends CLI/GUI/config/export summary to support selecting the new source and providing a backup password.
- Updates PDF attachment rendering to include non-exported/missing attachments with a “path / status” display, and adds synthetic fixtures + tests; bumps version to
0.8.0.
Reviewed changes
Copilot reviewed 47 out of 60 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_threema_android_backup.py | Regression + end-to-end tests for Threema Android backup import/export behavior. |
| tests/init.py | Marks tests as a package with a short module docstring. |
| src/chat_export/threema_android/normalize.py | Normalizes Android backup CSV rows into shared normalized conversation/message models. |
| src/chat_export/threema_android/models.py | Dataclasses + parsing helpers for contacts/groups/distribution lists/specs. |
| src/chat_export/threema_android/media.py | Parses file-message JSON bodies and optionally exports payloads with hashes/metadata. |
| src/chat_export/threema_android/importer.py | Implements the Threema Android backup importer and aggregates run metadata/counts. |
| src/chat_export/threema_android/identity.py | Implements legacy identity-backup decoding to obtain the owner Threema ID. |
| src/chat_export/threema_android/archive.py | Streaming access to AES-encrypted ZIP members + CSV parsing + version validation. |
| src/chat_export/threema_android/init.py | Package docstring for the new importer module. |
| src/chat_export/render/pdf_builder.py | Renders attachments even when not exported (shows status), updates attachment index table. |
| src/chat_export/orchestrator.py | Registers the new importer in the orchestrator importer map. |
| src/chat_export/gui.py | Adds new source label mapping + backup password field for Android backups; adjusts GUI error logging. |
| src/chat_export/export_summary.py | Adds backup version + source owner identity to manifest/summary; source-conditional settings fields. |
| src/chat_export/constants.py | Adds SOURCE_APP_THREEMA_ANDROID_BACKUP and includes it in supported sources list. |
| src/chat_export/config.py | Adds backup_password (repr-hidden) and validates it for Android backups. |
| src/chat_export/config_factory.py | Plumbs backup_password through config creation + validates required fields for the new source. |
| src/chat_export/cli.py | Adds --backup-password + secure prompt; avoids logging full parsed args; adjusts error logging. |
| src/chat_export/init.py | Bumps library version to 0.8.0. |
| README.md | Documents the new source for CLI + GUI and clarifies TECH report behavior for sources. |
| pyproject.toml | Bumps version to 0.8.0 and adds pyzipper dependency. |
| packaging/windows/ChatExportPDF.spec | Includes pyzipper as an optional package to collect for the Windows build. |
| Examples/ThreemaAndroidBackupSynthetic/source/settings | Synthetic fixture member: backup settings (version 27). |
| Examples/ThreemaAndroidBackupSynthetic/source/reaction_counts.csv | Synthetic fixture member: reaction count summary. |
| Examples/ThreemaAndroidBackupSynthetic/source/nonces.csv | Synthetic fixture member: nonce list. |
| Examples/ThreemaAndroidBackupSynthetic/source/nonces_d2d.csv | Synthetic fixture member: D2D nonce list. |
| Examples/ThreemaAndroidBackupSynthetic/source/nonce_counts.csv | Synthetic fixture member: nonce count summary. |
| Examples/ThreemaAndroidBackupSynthetic/source/message_media_00000000-0000-4000-8000-000000000007 | Synthetic fixture member: attachment payload (PDF). |
| Examples/ThreemaAndroidBackupSynthetic/source/message_0000000003.csv | Synthetic fixture member: empty direct chat CSV. |
| Examples/ThreemaAndroidBackupSynthetic/source/message_0000000002.csv | Synthetic fixture member: direct chat CSV with missing payload reference. |
| Examples/ThreemaAndroidBackupSynthetic/source/message_0000000001.csv | Synthetic fixture member: direct chat CSV covering text/quote/edit/delete/location/call/file cases. |
| Examples/ThreemaAndroidBackupSynthetic/source/identity | Synthetic fixture member: identity backup entry (test vector). |
| Examples/ThreemaAndroidBackupSynthetic/source/groups.csv | Synthetic fixture member: groups metadata CSV. |
| Examples/ThreemaAndroidBackupSynthetic/source/group_reactions.csv | Synthetic fixture member: group reactions CSV. |
| Examples/ThreemaAndroidBackupSynthetic/source/group_message_1000000001.csv | Synthetic fixture member: group messages CSV. |
| Examples/ThreemaAndroidBackupSynthetic/source/distribution_list.csv | Synthetic fixture member: distribution list metadata CSV. |
| Examples/ThreemaAndroidBackupSynthetic/source/distribution_list_message_media_00000000-0000-4000-8000-000000000203 | Synthetic fixture member: distribution-list attachment payload. |
| Examples/ThreemaAndroidBackupSynthetic/source/distribution_list_message_1.csv | Synthetic fixture member: distribution-list messages CSV. |
| Examples/ThreemaAndroidBackupSynthetic/source/contacts.csv | Synthetic fixture member: contacts CSV. |
| Examples/ThreemaAndroidBackupSynthetic/source/contact_reactions.csv | Synthetic fixture member: contact reactions CSV. |
| Examples/ThreemaAndroidBackupSynthetic/source/ballot.csv | Synthetic fixture member: poll metadata CSV. |
| Examples/ThreemaAndroidBackupSynthetic/source/ballot_vote.csv | Synthetic fixture member: poll votes CSV. |
| Examples/ThreemaAndroidBackupSynthetic/source/ballot_choice.csv | Synthetic fixture member: poll choices CSV. |
| Examples/ThreemaAndroidBackupSynthetic/README.txt | Documents the synthetic Android-backup fixture contents and regeneration steps. |
| Examples/ThreemaAndroidBackupSynthetic/expected.json | Expected counts/IDs used to validate importer outputs. |
| Examples/ThreemaAndroidBackupSynthetic/build_fixture.py | Script to regenerate the synthetic encrypted Android backup fixtures. |
| Examples/README.md | Adds the Android backup synthetic fixture to examples index. |
| CHANGELOG.md | Adds 0.8.0 changelog entry describing Threema Android backup support. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request adds support for encrypted Threema Android data backups.
Changed
Notes