mirror of
https://github.com/KnugiHK/WhatsApp-Chat-Exporter.git
synced 2026-06-03 06:40:26 +00:00
Merge branch 'dev'
This commit is contained in:
20
.github/workflows/ci.yml
vendored
20
.github/workflows/ci.yml
vendored
@@ -13,15 +13,19 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
os: [ubuntu-latest]
|
||||||
python-version: ["3.13", "3.14"]
|
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
||||||
include:
|
include:
|
||||||
- os: ubuntu-latest
|
- os: windows-latest
|
||||||
python-version: "3.10"
|
python-version: "3.13"
|
||||||
- os: ubuntu-latest
|
- os: macos-latest
|
||||||
python-version: "3.11"
|
python-version: "3.13"
|
||||||
- os: ubuntu-latest
|
- os: windows-11-arm
|
||||||
python-version: "3.12"
|
python-version: "3.13"
|
||||||
|
- os: macos-15-intel
|
||||||
|
python-version: "3.13"
|
||||||
|
- os: windows-latest
|
||||||
|
python-version: "3.14"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
|
|||||||
84
.github/workflows/compile-binary.yml
vendored
84
.github/workflows/compile-binary.yml
vendored
@@ -10,7 +10,6 @@ permissions:
|
|||||||
id-token: write
|
id-token: write
|
||||||
attestations: write
|
attestations: write
|
||||||
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
linux:
|
linux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -37,11 +36,10 @@ jobs:
|
|||||||
subject-path: ./wtsexporter_linux_x64
|
subject-path: ./wtsexporter_linux_x64
|
||||||
- uses: actions/upload-artifact@v6
|
- uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: binary-linux
|
name: binary-linux-x64
|
||||||
path: |
|
path: ./wtsexporter_linux_x64
|
||||||
./wtsexporter_linux_x64
|
|
||||||
|
|
||||||
windows:
|
windows-x64:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
@@ -57,19 +55,45 @@ jobs:
|
|||||||
- name: Build binary with Nuitka
|
- name: Build binary with Nuitka
|
||||||
run: |
|
run: |
|
||||||
python -m nuitka --onefile --include-data-file=./Whatsapp_Chat_Exporter/whatsapp.html=./Whatsapp_Chat_Exporter/whatsapp.html --assume-yes-for-downloads Whatsapp_Chat_Exporter --output-filename=wtsexporter
|
python -m nuitka --onefile --include-data-file=./Whatsapp_Chat_Exporter/whatsapp.html=./Whatsapp_Chat_Exporter/whatsapp.html --assume-yes-for-downloads Whatsapp_Chat_Exporter --output-filename=wtsexporter
|
||||||
Rename-Item -Path "wtsexporter.exe" -NewName "wtsexporter_x64.exe"
|
Rename-Item -Path "wtsexporter.exe" -NewName "wtsexporter_win_x64.exe"
|
||||||
Get-FileHash wtsexporter_x64.exe
|
Get-FileHash wtsexporter_win_x64.exe
|
||||||
- name: Generate artifact attestation
|
- name: Generate artifact attestation
|
||||||
uses: actions/attest-build-provenance@v3
|
uses: actions/attest-build-provenance@v3
|
||||||
with:
|
with:
|
||||||
subject-path: .\wtsexporter_x64.exe
|
subject-path: .\wtsexporter_win_x64.exe
|
||||||
- uses: actions/upload-artifact@v6
|
- uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: binary-windows
|
name: binary-windows-x64
|
||||||
path: |
|
path: .\wtsexporter_win_x64.exe
|
||||||
.\wtsexporter_x64.exe
|
|
||||||
|
|
||||||
macos:
|
windows-arm:
|
||||||
|
runs-on: windows-11-arm
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v6
|
||||||
|
with:
|
||||||
|
python-version: '3.13'
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install pycryptodome javaobj-py3 ordered-set zstandard nuitka==2.8.9
|
||||||
|
pip install .
|
||||||
|
- name: Build binary with Nuitka
|
||||||
|
run: |
|
||||||
|
python -m nuitka --onefile --include-data-file=./Whatsapp_Chat_Exporter/whatsapp.html=./Whatsapp_Chat_Exporter/whatsapp.html --assume-yes-for-downloads Whatsapp_Chat_Exporter --output-filename=wtsexporter
|
||||||
|
Rename-Item -Path "wtsexporter.exe" -NewName "wtsexporter_win_arm64.exe"
|
||||||
|
Get-FileHash wtsexporter_win_arm64.exe
|
||||||
|
- name: Generate artifact attestation
|
||||||
|
uses: actions/attest-build-provenance@v3
|
||||||
|
with:
|
||||||
|
subject-path: .\wtsexporter_win_arm64.exe
|
||||||
|
- uses: actions/upload-artifact@v6
|
||||||
|
with:
|
||||||
|
name: binary-windows-arm64
|
||||||
|
path: .\wtsexporter_win_arm64.exe
|
||||||
|
|
||||||
|
macos-arm:
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
@@ -86,7 +110,8 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
python -m nuitka --onefile \
|
python -m nuitka --onefile \
|
||||||
--include-data-file=./Whatsapp_Chat_Exporter/whatsapp.html=./Whatsapp_Chat_Exporter/whatsapp.html \
|
--include-data-file=./Whatsapp_Chat_Exporter/whatsapp.html=./Whatsapp_Chat_Exporter/whatsapp.html \
|
||||||
--assume-yes-for-downloads Whatsapp_Chat_Exporter --output-filename=wtsexporter_macos_arm64
|
--assume-yes-for-downloads Whatsapp_Chat_Exporter --output-filename=wtsexporter
|
||||||
|
mv wtsexporter wtsexporter_macos_arm64
|
||||||
shasum -a 256 wtsexporter_macos_arm64
|
shasum -a 256 wtsexporter_macos_arm64
|
||||||
- name: Generate artifact attestation
|
- name: Generate artifact attestation
|
||||||
uses: actions/attest-build-provenance@v3
|
uses: actions/attest-build-provenance@v3
|
||||||
@@ -94,7 +119,34 @@ jobs:
|
|||||||
subject-path: ./wtsexporter_macos_arm64
|
subject-path: ./wtsexporter_macos_arm64
|
||||||
- uses: actions/upload-artifact@v6
|
- uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: binary-macos
|
name: binary-macos-arm64
|
||||||
path: |
|
path: ./wtsexporter_macos_arm64
|
||||||
./wtsexporter_macos_arm64
|
|
||||||
|
|
||||||
|
macos-intel:
|
||||||
|
runs-on: macos-15-intel
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v6
|
||||||
|
with:
|
||||||
|
python-version: '3.13'
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install pycryptodome javaobj-py3 ordered-set zstandard nuitka==2.8.9
|
||||||
|
pip install .
|
||||||
|
- name: Build binary with Nuitka
|
||||||
|
run: |
|
||||||
|
python -m nuitka --onefile \
|
||||||
|
--include-data-file=./Whatsapp_Chat_Exporter/whatsapp.html=./Whatsapp_Chat_Exporter/whatsapp.html \
|
||||||
|
--assume-yes-for-downloads Whatsapp_Chat_Exporter --output-filename=wtsexporter
|
||||||
|
mv wtsexporter wtsexporter_macos_x64
|
||||||
|
shasum -a 256 wtsexporter_macos_x64
|
||||||
|
- name: Generate artifact attestation
|
||||||
|
uses: actions/attest-build-provenance@v3
|
||||||
|
with:
|
||||||
|
subject-path: ./wtsexporter_macos_x64
|
||||||
|
- uses: actions/upload-artifact@v6
|
||||||
|
with:
|
||||||
|
name: binary-macos-x64
|
||||||
|
path: ./wtsexporter_macos_x64
|
||||||
33
README.md
33
README.md
@@ -145,22 +145,24 @@ After extracting, you will get this:
|
|||||||
Invoke the wtsexporter with --help option will show you all options available.
|
Invoke the wtsexporter with --help option will show you all options available.
|
||||||
```sh
|
```sh
|
||||||
> wtsexporter --help
|
> wtsexporter --help
|
||||||
usage: wtsexporter [-h] [-a] [-i] [-e EXPORTED] [-w WA] [-m MEDIA] [-b BACKUP] [-d DB] [-k [KEY]]
|
usage: wtsexporter [-h] [--debug] [-a] [-i] [-e EXPORTED] [-w WA] [-m MEDIA] [-b BACKUP] [-d DB] [-k [KEY]]
|
||||||
[--call-db [CALL_DB_IOS]] [--wab WAB] [-o OUTPUT] [-j [JSON]] [--txt [TEXT_FORMAT]] [--no-html]
|
[--call-db [CALL_DB_IOS]] [--wab WAB] [-o OUTPUT] [-j [JSON]] [--txt [TEXT_FORMAT]] [--no-html]
|
||||||
[--size [SIZE]] [--avoid-encoding-json] [--pretty-print-json [PRETTY_PRINT_JSON]] [--per-chat]
|
[--size [SIZE]] [--no-reply] [--avoid-encoding-json] [--pretty-print-json [PRETTY_PRINT_JSON]]
|
||||||
[--import] [-t TEMPLATE] [--offline OFFLINE] [--no-avatar] [--experimental-new-theme]
|
[--tg] [--per-chat] [--import] [-t TEMPLATE] [--offline OFFLINE] [--no-avatar] [--old-theme]
|
||||||
[--headline HEADLINE] [-c] [--create-separated-media] [--time-offset {-12 to 14}] [--date DATE]
|
[--headline HEADLINE] [-c] [--create-separated-media] [--time-offset {-12 to 14}] [--date DATE]
|
||||||
[--date-format FORMAT] [--include [phone number ...]] [--exclude [phone number ...]]
|
[--date-format FORMAT] [--include [phone number ...]] [--exclude [phone number ...]]
|
||||||
[--dont-filter-empty] [--enrich-from-vcards ENRICH_FROM_VCARDS]
|
[--dont-filter-empty] [--enrich-from-vcards ENRICH_FROM_VCARDS]
|
||||||
[--default-country-code DEFAULT_COUNTRY_CODE] [-s] [--check-update] [--assume-first-as-me]
|
[--default-country-code DEFAULT_COUNTRY_CODE] [--incremental-merge] [--source-dir SOURCE_DIR]
|
||||||
[--business] [--decrypt-chunk-size DECRYPT_CHUNK_SIZE]
|
[--target-dir TARGET_DIR] [-s] [--check-update] [--assume-first-as-me] [--business]
|
||||||
[--max-bruteforce-worker MAX_BRUTEFORCE_WORKER]
|
[--decrypt-chunk-size DECRYPT_CHUNK_SIZE] [--max-bruteforce-worker MAX_BRUTEFORCE_WORKER]
|
||||||
|
[--no-banner]
|
||||||
|
|
||||||
A customizable Android and iOS/iPadOS WhatsApp database parser that will give you the history of your WhatsApp
|
A customizable Android and iOS/iPadOS WhatsApp database parser that will give you the history of your WhatsApp
|
||||||
conversations in HTML and JSON. Android Backup Crypt12, Crypt14 and Crypt15 supported.
|
conversations in HTML and JSON. Android Backup Crypt12, Crypt14 and Crypt15 supported.
|
||||||
|
|
||||||
options:
|
options:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
|
--debug Enable debug mode
|
||||||
|
|
||||||
Device Type:
|
Device Type:
|
||||||
-a, --android Define the target as Android
|
-a, --android Define the target as Android
|
||||||
@@ -188,12 +190,14 @@ Output Options:
|
|||||||
--no-html Do not output html files
|
--no-html Do not output html files
|
||||||
--size, --output-size, --split [SIZE]
|
--size, --output-size, --split [SIZE]
|
||||||
Maximum (rough) size of a single output file in bytes, 0 for auto
|
Maximum (rough) size of a single output file in bytes, 0 for auto
|
||||||
|
--no-reply Do not process replies (iOS only) (default: handle replies)
|
||||||
|
|
||||||
JSON Options:
|
JSON Options:
|
||||||
--avoid-encoding-json
|
--avoid-encoding-json
|
||||||
Don't encode non-ascii characters in the output JSON files
|
Don't encode non-ascii characters in the output JSON files
|
||||||
--pretty-print-json [PRETTY_PRINT_JSON]
|
--pretty-print-json [PRETTY_PRINT_JSON]
|
||||||
Pretty print the output JSON.
|
Pretty print the output JSON.
|
||||||
|
--tg, --telegram Output the JSON in a format compatible with Telegram export (implies json-per-chat)
|
||||||
--per-chat Output the JSON file per chat
|
--per-chat Output the JSON file per chat
|
||||||
--import Import JSON file and convert to HTML output
|
--import Import JSON file and convert to HTML output
|
||||||
|
|
||||||
@@ -202,8 +206,7 @@ HTML Options:
|
|||||||
Path to custom HTML template
|
Path to custom HTML template
|
||||||
--offline OFFLINE Relative path to offline static files
|
--offline OFFLINE Relative path to offline static files
|
||||||
--no-avatar Do not render avatar in HTML output
|
--no-avatar Do not render avatar in HTML output
|
||||||
--experimental-new-theme
|
--old-theme Use the old Telegram-alike theme
|
||||||
Use the newly designed WhatsApp-alike theme
|
|
||||||
--headline HEADLINE The custom headline for the HTML output. Use '??' as a placeholder for the chat name
|
--headline HEADLINE The custom headline for the HTML output. Use '??' as a placeholder for the chat name
|
||||||
|
|
||||||
Media Handling:
|
Media Handling:
|
||||||
@@ -232,12 +235,11 @@ Contact Enrichment:
|
|||||||
will be used. 1 is for US, 66 for Thailand etc. Most likely use the number of your own country
|
will be used. 1 is for US, 66 for Thailand etc. Most likely use the number of your own country
|
||||||
|
|
||||||
Incremental Merging:
|
Incremental Merging:
|
||||||
--incremental-merge Performs an incremental merge of two exports. Requires setting both --source-
|
--incremental-merge Performs an incremental merge of two exports. Requires setting both --source-dir and --target-
|
||||||
dir and --target-dir. The chats (JSON files only) and media from the source
|
dir. The chats (JSON files only) and media from the source directory will be merged into the
|
||||||
directory will be merged into the target directory. No chat messages or media
|
target directory. No chat messages or media will be deleted from the target directory; only
|
||||||
will be deleted from the target directory; only new chat messages and media
|
new chat messages and media will be added to it. This enables chat messages and media to be
|
||||||
will be added to it. This enables chat messages and media to be deleted from
|
deleted from the device to free up space, while ensuring they are preserved in the exported
|
||||||
the device to free up space, while ensuring they are preserved in the exported
|
|
||||||
backups.
|
backups.
|
||||||
--source-dir SOURCE_DIR
|
--source-dir SOURCE_DIR
|
||||||
Sets the source directory. Used for performing incremental merges.
|
Sets the source directory. Used for performing incremental merges.
|
||||||
@@ -253,8 +255,9 @@ Miscellaneous:
|
|||||||
Specify the chunk size for decrypting iOS backup, which may affect the decryption speed.
|
Specify the chunk size for decrypting iOS backup, which may affect the decryption speed.
|
||||||
--max-bruteforce-worker MAX_BRUTEFORCE_WORKER
|
--max-bruteforce-worker MAX_BRUTEFORCE_WORKER
|
||||||
Specify the maximum number of worker for bruteforce decryption.
|
Specify the maximum number of worker for bruteforce decryption.
|
||||||
|
--no-banner Do not show the banner
|
||||||
|
|
||||||
WhatsApp Chat Exporter: 0.13.0rc1 Licensed with MIT. See https://wts.knugi.dev/docs?dest=osl for all open source
|
WhatsApp Chat Exporter: 0.13.0rc2 Licensed with MIT. See https://wts.knugi.dev/docs?dest=osl for all open source
|
||||||
licenses.
|
licenses.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ WTSEXPORTER_BANNER = f"""=======================================================
|
|||||||
╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝
|
╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝
|
||||||
|
|
||||||
WhatsApp Chat Exporter: A customizable Android and iOS/iPadOS WhatsApp database parser
|
WhatsApp Chat Exporter: A customizable Android and iOS/iPadOS WhatsApp database parser
|
||||||
Version: {__version__}
|
{f"Version: {__version__}".center(104)}
|
||||||
========================================================================================================"""
|
========================================================================================================"""
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -178,6 +178,17 @@ def messages(db, data, media_folder, timezone_offset, filter_date, filter_chat,
|
|||||||
"""
|
"""
|
||||||
c.execute(messages_query)
|
c.execute(messages_query)
|
||||||
|
|
||||||
|
reply_query = """SELECT ZSTANZAID,
|
||||||
|
ZTEXT,
|
||||||
|
ZTITLE
|
||||||
|
FROM ZWAMESSAGE
|
||||||
|
LEFT JOIN ZWAMEDIAITEM
|
||||||
|
ON ZWAMESSAGE.Z_PK = ZWAMEDIAITEM.ZMESSAGE
|
||||||
|
WHERE ZTEXT IS NOT NULL
|
||||||
|
OR ZTITLE IS NOT NULL;"""
|
||||||
|
cursor2.execute(reply_query)
|
||||||
|
message_map = {row[0][:17]: row[1] or row[2] for row in cursor2.fetchall() if row[0]}
|
||||||
|
|
||||||
# Process each message
|
# Process each message
|
||||||
i = 0
|
i = 0
|
||||||
content = c.fetchone()
|
content = c.fetchone()
|
||||||
@@ -207,7 +218,7 @@ def messages(db, data, media_folder, timezone_offset, filter_date, filter_chat,
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Process message data
|
# Process message data
|
||||||
invalid = process_message_data(message, content, is_group_message, data, cursor2, no_reply)
|
invalid = process_message_data(message, content, is_group_message, data, message_map, no_reply)
|
||||||
|
|
||||||
# Add valid messages to chat
|
# Add valid messages to chat
|
||||||
if not invalid:
|
if not invalid:
|
||||||
@@ -221,7 +232,7 @@ def messages(db, data, media_folder, timezone_offset, filter_date, filter_chat,
|
|||||||
logger.info(f"Processed {total_row_number} messages{CLEAR_LINE}")
|
logger.info(f"Processed {total_row_number} messages{CLEAR_LINE}")
|
||||||
|
|
||||||
|
|
||||||
def process_message_data(message, content, is_group_message, data, cursor2, no_reply):
|
def process_message_data(message, content, is_group_message, data, message_map, no_reply):
|
||||||
"""Process and set message data from content row."""
|
"""Process and set message data from content row."""
|
||||||
# Handle group sender info
|
# Handle group sender info
|
||||||
if is_group_message and content["ZISFROMME"] == 0:
|
if is_group_message and content["ZISFROMME"] == 0:
|
||||||
@@ -247,14 +258,7 @@ def process_message_data(message, content, is_group_message, data, cursor2, no_r
|
|||||||
if content["ZMETADATA"] is not None and content["ZMETADATA"].startswith(b"\x2a\x14") and not no_reply:
|
if content["ZMETADATA"] is not None and content["ZMETADATA"].startswith(b"\x2a\x14") and not no_reply:
|
||||||
quoted = content["ZMETADATA"][2:19]
|
quoted = content["ZMETADATA"][2:19]
|
||||||
message.reply = quoted.decode()
|
message.reply = quoted.decode()
|
||||||
cursor2.execute(f"""SELECT ZTEXT
|
message.quoted_data = message_map.get(message.reply)
|
||||||
FROM ZWAMESSAGE
|
|
||||||
WHERE ZSTANZAID LIKE '{message.reply}%'""")
|
|
||||||
quoted_content = cursor2.fetchone()
|
|
||||||
if quoted_content and "ZTEXT" in quoted_content:
|
|
||||||
message.quoted_data = quoted_content["ZTEXT"]
|
|
||||||
else:
|
|
||||||
message.quoted_data = None
|
|
||||||
|
|
||||||
# Handle stickers
|
# Handle stickers
|
||||||
if content["ZMESSAGETYPE"] == 15:
|
if content["ZMESSAGETYPE"] == 15:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "whatsapp-chat-exporter"
|
name = "whatsapp-chat-exporter"
|
||||||
version = "0.13.0rc1"
|
version = "0.13.0rc2"
|
||||||
description = "A Whatsapp database parser that provides history of your Whatsapp conversations in HTML and JSON. Android, iOS, iPadOS, Crypt12, Crypt14, Crypt15 supported."
|
description = "A Whatsapp database parser that provides history of your Whatsapp conversations in HTML and JSON. Android, iOS, iPadOS, Crypt12, Crypt14, Crypt15 supported."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
authors = [
|
authors = [
|
||||||
|
|||||||
Reference in New Issue
Block a user