Compare commits

...

59 Commits

Author SHA1 Message Date
Simon Laux
5b5c900cb9 also export qoutes, message state and is_forwarded 2021-06-01 23:58:04 +02:00
Simon Laux
b87ca6e747 restructure code 2021-06-01 23:58:04 +02:00
Simon Laux
850f7e1174 output daymarker and message error 2021-06-01 23:58:04 +02:00
Simon Laux
9f2b5feda2 move getting and writing message info to packing-
step, this could decrease memory usage
2021-06-01 23:58:04 +02:00
Simon Laux
b8cbcc6648 add export_timestamp to chat.json 2021-06-01 23:58:04 +02:00
Simon Laux
584d28f807 update code that it compiles with current core
make contact deduping more reliable
2021-06-01 23:58:04 +02:00
Simon Laux
241111470f export locations 2021-06-01 23:58:03 +02:00
Simon Laux
4bf07ccc71 repl export-chat-requires destination path
and combind the public accessible functions into one
2021-06-01 23:58:03 +02:00
Simon Laux
897d2f4a08 add some ducumentation 2021-06-01 23:58:03 +02:00
Simon Laux
a81096aa36 rename files in exported zip 2021-06-01 23:58:03 +02:00
Simon Laux
b1c9342631 save raw mime headers under the eml
extention instead of the text extention
2021-06-01 23:58:03 +02:00
Simon Laux
0c8aad2102 export message mime-headers when availible 2021-06-01 23:58:03 +02:00
Simon Laux
82253e1e30 fix deduplication of blob files 2021-06-01 23:58:03 +02:00
Simon Laux
aa953687bf add message info 2021-06-01 23:58:03 +02:00
Simon Laux
9f2f2ca1c0 [works again] export json, adjust to work in async
and remove html stuff
2021-06-01 23:58:03 +02:00
Simon Laux
54637004cd [still broken]* A bit progress on:
- transforming the export format to json
- async
- cleanup cod
(*broken state, just a commit to save progress)
2021-06-01 23:58:03 +02:00
Simon Laux
da9f45d9ff state of previous export chat pr 2021-06-01 23:58:01 +02:00
dependabot[bot]
d8ba466c6a Merge pull request #2452 from deltachat/dependabot/cargo/thiserror-1.0.25 2021-05-28 23:06:58 +00:00
dependabot[bot]
0c2a3c8347 Merge pull request #2453 from deltachat/dependabot/cargo/libc-0.2.95 2021-05-28 22:43:59 +00:00
Hocuri
e3e2adeea5 Fix all outgoing messages popping up in selfchat (#2456)
Fix https://github.com/deltachat/deltachat-android/issues/1940, fix https://github.com/deltachat/deltachat-core-rust/issues/2220 (I assume these are the same bug)

The problem was:
- Gmail adds a header `Bcc: <self-address>` to our bcc-self message
- `to_id` was just set to the first recipient, in this case _self_
- it was seen that `to_id` is _self_, so it's a self-sent message
2021-05-28 20:02:46 +02:00
Hocuri
46e901be78 Fix benchmark compile error (#2457) 2021-05-28 18:48:13 +02:00
dependabot[bot]
d899a38d17 cargo: bump libc from 0.2.94 to 0.2.95
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.94 to 0.2.95.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.94...0.2.95)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-26 06:30:24 +00:00
dependabot[bot]
b60994b313 cargo: bump thiserror from 1.0.24 to 1.0.25
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.24 to 1.0.25.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.24...1.0.25)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-24 07:55:01 +00:00
link2xt
8b19b6f9fe ci: don't build circleci on branches 2021-05-23 19:34:59 +03:00
link2xt
ea88a567f9 ci: require that tag contains at least 1 character 2021-05-23 19:32:31 +03:00
link2xt
38c23104da ci: build wheels only for tags 2021-05-23 19:30:10 +03:00
link2xt
2a83147d90 tox: fix "test command found but not installed in testenv" warning
Determine architecture from python instead of using sh and uname
2021-05-23 18:40:40 +03:00
link2xt
7e3bfd38f0 scripts: use rust 1.52.1 for docker-coredeps-arm64
Building aarch64 wheels under qemu takes a long time.
rust 1.52.1 includes fix for cargo that may result in
compilation being stuck: https://github.com/rust-lang/cargo/pull/9201
2021-05-23 18:20:54 +03:00
link2xt
8b78e12b36 Set ServerAliveInterval to ping SSH server every 30 seconds
Otherwise connection may be dropped if there is no output for some time.
2021-05-23 13:16:16 +03:00
link2xt
15660f2741 Set ServerAliveInterval to ping SSH server every 30 seconds
Otherwise connection may be dropped if there is no output for some time.
2021-05-23 13:10:24 +03:00
link2xt
03520fbd4b Increase wheel building timeout again 2021-05-23 13:01:21 +03:00
link2xt
b1228cbbe5 ci: increase remote python packaging timeout to 30m 2021-05-23 11:43:30 +03:00
link2xt
09f5b015bb python: support running auditwheels for aarch64 2021-05-23 11:43:30 +03:00
link2xt
67ca93b093 ci: build aarch64 wheels
Also drop python 3.6, aarch64 wheels fail to build there
2021-05-23 10:55:01 +03:00
link2xt
dabf31204c scripts: do not build py310 wheels
There is no py310 cffi wheel yet.
2021-05-23 09:50:24 +03:00
link2xt
c22580e07f scripts: build wheels for python 3.6-3.10
These are all versions supported by manylinux2014 now
2021-05-23 09:26:16 +03:00
link2xt
0028f579b6 Update docker-coredeps to use python3.6
Python 3.5 is removed from the latest manylinux2014 images
2021-05-23 09:24:58 +03:00
link2xt
9522240992 scripts: add docker-coredeps-arm64 2021-05-23 09:05:07 +03:00
link2xt
8ab3415c58 CMakeLists.txt: specify only C language
By default C and CXX are enabled.
This resulted in unnecessary C++ compiler check.
2021-05-22 20:29:02 +03:00
link2xt
e858fca356 dc_receive_imf: add python test for server-side message moving
There was a bugreport for previous versions of DC that BCC-self
messages are not marked as seen if server-side Sieve rule moves them.

This test is an unsuccessful attempt to reproduce the bug,
which was confirmed to be fixed.
2021-05-22 18:53:16 +03:00
link2xt
7d4affcc8d python: disable BCC-self in test_markseen_message_and_mdn
This test checks that MDN is marked as seen on ac1.  Because ac1 also
receives BCC-self, it is possible that event of marking this message
as seen is confused with marking MDN as seen, and the test passes even
if MDN is not marked as seen.  Explicitly disabling BCC-self for ac1
ensures it receives only one message (MDN).

Also start direct_imap as early as possible, before sending the
message. It is possible now, because BCC-self is not sent.
2021-05-22 18:52:55 +03:00
link2xt
60d596bb0e README: remove "remote tests" badge
This CI workflow does not exist anymore.
2021-05-22 16:17:25 +03:00
dependabot[bot]
c57bfde010 Merge pull request #2449 from deltachat/dependabot/cargo/rustyline-8.2.0 2021-05-22 12:37:04 +00:00
dependabot[bot]
afd7e7eaac cargo: bump rustyline from 8.1.0 to 8.2.0
Bumps [rustyline](https://github.com/kkawakam/rustyline) from 8.1.0 to 8.2.0.
- [Release notes](https://github.com/kkawakam/rustyline/releases)
- [Changelog](https://github.com/kkawakam/rustyline/blob/master/History.md)
- [Commits](https://github.com/kkawakam/rustyline/compare/v8.1.0...v8.2.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-21 06:51:43 +00:00
dependabot[bot]
cfc324c95b Merge pull request #2448 from deltachat/dependabot/cargo/rustyline-8.1.0 2021-05-19 23:28:31 +00:00
dependabot[bot]
aa5d6077a8 cargo: bump rustyline from 8.0.0 to 8.1.0
Bumps [rustyline](https://github.com/kkawakam/rustyline) from 8.0.0 to 8.1.0.
- [Release notes](https://github.com/kkawakam/rustyline/releases)
- [Changelog](https://github.com/kkawakam/rustyline/blob/master/History.md)
- [Commits](https://github.com/kkawakam/rustyline/compare/v8.0.0...v8.1.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-19 23:02:42 +00:00
dependabot[bot]
4a2beac6fc Merge pull request #2447 from deltachat/dependabot/cargo/async-std-resolver-0.20.3 2021-05-19 21:37:01 +00:00
dependabot[bot]
b5dc954408 cargo: bump async-std-resolver from 0.20.2 to 0.20.3
Bumps [async-std-resolver](https://github.com/bluejekyll/trust-dns) from 0.20.2 to 0.20.3.
- [Release notes](https://github.com/bluejekyll/trust-dns/releases)
- [Changelog](https://github.com/bluejekyll/trust-dns/blob/v0.20.3/CHANGELOG.md)
- [Commits](https://github.com/bluejekyll/trust-dns/compare/v0.20.2...v0.20.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-17 07:48:56 +00:00
Hocuri
a9f5077cf9 Make scan_folders work when inbox is not watched (#2446)
When watch_inbox was off, scan_folders failed and a toast "IMAP operation attempted while it is torn down" was shown.

--

The problem was:

When inbox_watch is off, scan_folders() is called at 244260a978/src/scheduler.rs (L107) but connect_configured() is not called before.



* Add test

* Don't only setup handle, but connect_configured() in scan_folders()
2021-05-16 22:18:38 +02:00
link2xt
09280508bc ci: run python tests on github workers 2021-05-16 16:30:40 +03:00
link2xt
4391835a8d qr: remove outdated comment
The comment referred to using Param::SetLongitude instead of "n".
It was fixed in 6bb0c164f9
2021-05-15 17:15:13 +03:00
dependabot[bot]
05f9ac0583 Merge pull request #2440 from deltachat/dependabot/cargo/sha-1-0.9.6 2021-05-15 01:10:27 +00:00
dependabot[bot]
fd9d632cd6 cargo: bump sha-1 from 0.9.5 to 0.9.6
Bumps [sha-1](https://github.com/RustCrypto/hashes) from 0.9.5 to 0.9.6.
- [Release notes](https://github.com/RustCrypto/hashes/releases)
- [Commits](https://github.com/RustCrypto/hashes/compare/sha-1-v0.9.5...sha-1-v0.9.6)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-15 00:56:03 +00:00
dependabot[bot]
c9e626322b Merge pull request #2439 from deltachat/dependabot/cargo/sha2-0.9.5 2021-05-15 00:54:40 +00:00
dependabot[bot]
f343ec47b4 Merge pull request #2438 from deltachat/dependabot/cargo/futures-0.3.15 2021-05-15 00:49:12 +00:00
dependabot[bot]
efb1534d5c Merge pull request #2441 from deltachat/dependabot/cargo/serde-1.0.126 2021-05-15 00:48:13 +00:00
dependabot[bot]
6ec765cad6 cargo: bump serde from 1.0.125 to 1.0.126
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.125 to 1.0.126.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.125...v1.0.126)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-13 07:02:22 +00:00
dependabot[bot]
372a4ee539 cargo: bump sha2 from 0.9.4 to 0.9.5
Bumps [sha2](https://github.com/RustCrypto/hashes) from 0.9.4 to 0.9.5.
- [Release notes](https://github.com/RustCrypto/hashes/releases)
- [Commits](https://github.com/RustCrypto/hashes/compare/sha2-v0.9.4...sha2-v0.9.5)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-12 06:25:22 +00:00
dependabot[bot]
418b591602 cargo: bump futures from 0.3.14 to 0.3.15
Bumps [futures](https://github.com/rust-lang/futures-rs) from 0.3.14 to 0.3.15.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.14...0.3.15)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-12 06:25:14 +00:00
31 changed files with 748 additions and 145 deletions

View File

@@ -27,7 +27,10 @@ jobs:
- checkout
# the following commands on success produces
# workspace/{wheelhouse,py-docs} as artefact directories
- run: bash scripts/remote_python_packaging.sh
- run:
# building aarch64 packages under qemu is very slow
no_output_timeout: 60m
command: bash scripts/remote_python_packaging.sh
- persist_to_workspace:
root: workspace
paths:
@@ -51,18 +54,24 @@ workflows:
jobs:
- remote_python_packaging:
filters:
tags:
only: /.+/
branches:
only: master
ignore: /.*/
- build_doxygen:
filters:
tags:
only: /.+/
branches:
ignore: /.*/
- upload_docs_wheels:
requires:
- remote_python_packaging
- build_doxygen
filters:
tags:
only: /.+/
branches:
only: master
- build_doxygen:
filters:
branches:
only: master
ignore: /.*/

View File

@@ -65,26 +65,16 @@ jobs:
build_and_test:
name: Build and test
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.experimental }}
strategy:
matrix:
# macOS disabled due to random failures related to caching
#os: [ubuntu-latest, windows-latest, macOS-latest]
os: [ubuntu-latest, windows-latest]
rust: [1.50.0]
experimental: [false]
# include:
# - os: ubuntu-latest
# rust: nightly
# experimental: true
# - os: windows-latest
# rust: nightly
# experimental: true
# - os: macOS-latest
# rust: nightly
# experimental: true
include:
- os: ubuntu-latest
rust: 1.50.0
python: 3.6
- os: windows-latest
rust: 1.50.0
python: false # Python bindings compilation on Windows is not supported.
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@master
@@ -125,3 +115,29 @@ jobs:
with:
command: test
args: --all
- name: install python
if: ${{ matrix.python }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python }}
- name: install tox
if: ${{ matrix.python }}
run: pip install tox
- name: build C library
if: ${{ matrix.python }}
uses: actions-rs/cargo@v1
with:
command: build
args: -p deltachat_ffi
- name: run python tests
if: ${{ matrix.python }}
env:
DCC_NEW_TMP_EMAIL: ${{ secrets.DCC_NEW_TMP_EMAIL }}
DCC_RS_TARGET: debug
DCC_RS_DEV: ${{ github.workspace }}
working-directory: python
run: tox -e lint,doc,py3

View File

@@ -1,18 +0,0 @@
name: Remote tests
on: [push]
jobs:
remote_tests_python:
name: Remote Python tests
runs-on: ubuntu-latest
env:
DCC_NEW_TMP_EMAIL: ${{ secrets.DCC_NEW_TMP_EMAIL }}
steps:
- uses: actions/checkout@v2
- run: mkdir -m 700 -p ~/.ssh
- run: touch ~/.ssh/id_ed25519
- run: chmod 600 ~/.ssh/id_ed25519
- run: 'echo "$SSH_KEY" | base64 -d > ~/.ssh/id_ed25519'
shell: bash
env:
SSH_KEY: ${{ secrets.SSH_KEY }}
- run: scripts/remote_tests_python.sh "deltachat-core/python/${{ github.ref }}/${{ github.run_number }}"

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.16)
project(deltachat)
project(deltachat LANGUAGES C)
find_program(CARGO cargo)

175
Cargo.lock generated
View File

@@ -374,9 +374,9 @@ dependencies = [
[[package]]
name = "async-std-resolver"
version = "0.20.2"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d613d619c2886fc0f4b5a777eceab405b23de82d73f0fc61ae402fdb9bc6fb2"
checksum = "ed4e2c3da14d8ad45acb1e3191db7a918e9505b6f155b218e70a7c9a1a48c638"
dependencies = [
"async-std",
"async-trait",
@@ -637,6 +637,27 @@ version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bzip2"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b"
dependencies = [
"bzip2-sys",
"libc",
]
[[package]]
name = "bzip2-sys"
version = "0.1.10+1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17fa3d1ac1ca21c5c4e36a97f3c3eb25084576f6fc47bf0139c1123434216c6c"
dependencies = [
"cc",
"libc",
"pkg-config",
]
[[package]]
name = "cache-padded"
version = "1.1.1"
@@ -748,6 +769,17 @@ dependencies = [
"cc",
]
[[package]]
name = "clipboard-win"
version = "4.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e4ea1881992efc993e4dc50a324cdbd03216e41bdc8385720ff47efc9bd2ca8"
dependencies = [
"error-code",
"str-buf",
"winapi",
]
[[package]]
name = "color_quant"
version = "1.1.0"
@@ -815,9 +847,12 @@ checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b"
[[package]]
name = "cpufeatures"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cd5a7748210e7ec1a9696610b1015e6e31fbf58f77a160801f124bd1c36592a"
checksum = "dec1028182c380cc45a2e2c5ec841134f2dfd0f8f5f0a5bcd68004f81b5efdf4"
dependencies = [
"libc",
]
[[package]]
name = "cpuid-bool"
@@ -1161,6 +1196,7 @@ dependencies = [
"toml",
"url",
"uuid",
"zip",
]
[[package]]
@@ -1452,6 +1488,16 @@ dependencies = [
"termcolor",
]
[[package]]
name = "error-code"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5115567ac25674e0043e472be13d14e537f37ea8aa4bdc4aef0c89add1db1ff"
dependencies = [
"libc",
"str-buf",
]
[[package]]
name = "escaper"
version = "0.1.1"
@@ -1497,6 +1543,16 @@ dependencies = [
"instant",
]
[[package]]
name = "fd-lock"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0010f02effd88c702318c5dde0463206be67495d0b4d906ba7c0a8f166cc7f06"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "filetime"
version = "0.2.14"
@@ -1552,21 +1608,11 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "fs2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "futures"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253"
checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27"
dependencies = [
"futures-channel",
"futures-core",
@@ -1579,9 +1625,9 @@ dependencies = [
[[package]]
name = "futures-channel"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25"
checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2"
dependencies = [
"futures-core",
"futures-sink",
@@ -1589,15 +1635,15 @@ dependencies = [
[[package]]
name = "futures-core"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815"
checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"
[[package]]
name = "futures-executor"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d"
checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79"
dependencies = [
"futures-core",
"futures-task",
@@ -1606,9 +1652,9 @@ dependencies = [
[[package]]
name = "futures-io"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04"
checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1"
[[package]]
name = "futures-lite"
@@ -1627,10 +1673,11 @@ dependencies = [
[[package]]
name = "futures-macro"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b"
checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121"
dependencies = [
"autocfg 1.0.1",
"proc-macro-hack",
"proc-macro2",
"quote",
@@ -1639,22 +1686,23 @@ dependencies = [
[[package]]
name = "futures-sink"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23"
checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282"
[[package]]
name = "futures-task"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc"
checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae"
[[package]]
name = "futures-util"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025"
checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967"
dependencies = [
"autocfg 1.0.1",
"futures-channel",
"futures-core",
"futures-io",
@@ -2102,9 +2150,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.94"
version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36"
[[package]]
name = "libm"
@@ -3154,14 +3202,15 @@ dependencies = [
[[package]]
name = "rustyline"
version = "8.0.0"
version = "8.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e1b597fcd1eeb1d6b25b493538e5aa19629eb08932184b85fef931ba87e893"
checksum = "fbd4eaf7a7738f76c98e4f0395253ae853be3eb018f7b0bb57fe1b6c17e31874"
dependencies = [
"bitflags",
"cfg-if 1.0.0",
"clipboard-win",
"dirs-next",
"fs2",
"fd-lock",
"libc",
"log",
"memchr",
@@ -3271,9 +3320,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
version = "1.0.125"
version = "1.0.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
dependencies = [
"serde_derive",
]
@@ -3290,9 +3339,9 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.125"
version = "1.0.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
dependencies = [
"proc-macro2",
"quote",
@@ -3336,9 +3385,9 @@ dependencies = [
[[package]]
name = "sha-1"
version = "0.9.5"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b659df5fc3ce22274daac600ffb845300bd2125bcfaec047823075afdab81c00"
checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16"
dependencies = [
"block-buffer",
"cfg-if 1.0.0",
@@ -3355,9 +3404,9 @@ checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
[[package]]
name = "sha2"
version = "0.9.4"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8f6b75b17576b792bef0db1bcc4b8b8bcdf9506744cf34b974195487af6cff2"
checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12"
dependencies = [
"block-buffer",
"cfg-if 1.0.0",
@@ -3542,6 +3591,12 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "str-buf"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d44a3643b4ff9caf57abcee9c2c621d6c03d9135e0d8b589bd9afb5992cb176a"
[[package]]
name = "stream-cipher"
version = "0.7.1"
@@ -3658,18 +3713,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.24"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.24"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d"
dependencies = [
"proc-macro2",
"quote",
@@ -3771,9 +3826,9 @@ dependencies = [
[[package]]
name = "trust-dns-proto"
version = "0.20.2"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "952a078337565ba39007de99b151770f41039253a31846f0a3d5cd5a4ac8eedf"
checksum = "ad0d7f5db438199a6e2609debe3f69f808d074e0a2888ee0bccb45fe234d03f4"
dependencies = [
"async-trait",
"cfg-if 1.0.0",
@@ -3795,9 +3850,9 @@ dependencies = [
[[package]]
name = "trust-dns-resolver"
version = "0.20.2"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da9c97f7d103e0f94dbe384a57908833505ae5870126492f166821b7cf685589"
checksum = "f6ad17b608a64bd0735e67bde16b0636f8aa8591f831a25d18443ed00a699770"
dependencies = [
"cfg-if 1.0.0",
"futures-util",
@@ -4179,3 +4234,17 @@ dependencies = [
"syn",
"synstructure",
]
[[package]]
name = "zip"
version = "0.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c83dc9b784d252127720168abd71ea82bf8c3d96b17dc565b5e2a02854f2b27"
dependencies = [
"byteorder",
"bzip2",
"crc32fast",
"flate2",
"thiserror",
"time 0.1.44",
]

View File

@@ -19,7 +19,7 @@ anyhow = "1.0.40"
async-imap = "0.5.0"
async-native-tls = { version = "0.3.3" }
async-smtp = { git = "https://github.com/async-email/async-smtp", rev="2275fd8d13e39b2c58d6605c786ff06ff9e05708" }
async-std-resolver = "0.20.2"
async-std-resolver = "0.20.3"
async-std = { version = "~1.9.0", features = ["unstable"] }
async-tar = "0.3.0"
async-trait = "0.1.50"
@@ -33,14 +33,14 @@ dirs = { version = "3.0.2", optional=true }
email = { git = "https://github.com/deltachat/rust-email", branch = "master" }
encoded-words = { git = "https://github.com/async-email/encoded-words", branch="master" }
escaper = "0.1.1"
futures = "0.3.14"
futures = "0.3.15"
hex = "0.4.0"
image = { version = "0.23.5", default-features=false, features = ["gif", "jpeg", "ico", "png", "pnm", "webp", "bmp"] }
indexmap = "1.3.0"
itertools = "0.10.0"
kamadak-exif = "0.5"
lettre_email = { git = "https://github.com/deltachat/lettre", branch = "master" }
libc = "0.2.51"
libc = "0.2.95"
log = {version = "0.4.8", optional = true }
mailparse = "0.13.4"
native-tls = "0.2.3"
@@ -58,21 +58,22 @@ rand = "0.7.0"
regex = "1.4.6"
rusqlite = "0.25"
rust-hsluv = "0.1.4"
rustyline = { version = "8.0.0", optional = true }
rustyline = { version = "8.2.0", optional = true }
sanitize-filename = "0.3.0"
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
sha-1 = "0.9.5"
sha2 = "0.9.4"
sha-1 = "0.9.6"
sha2 = "0.9.5"
smallvec = "1.0.0"
stop-token = "0.2.0"
strum = "0.20.0"
strum_macros = "0.20.1"
surf = { version = "2.0.0-alpha.4", default-features = false, features = ["h1-client"] }
thiserror = "1.0.14"
thiserror = "1.0.25"
toml = "0.5.6"
url = "2.2.2"
uuid = { version = "0.8", features = ["serde", "v4"] }
zip = "0.5.12"
[dev-dependencies]
ansi_term = "0.12.0"

View File

@@ -3,7 +3,6 @@
> Deltachat-core written in Rust
[![Rust CI](https://github.com/deltachat/deltachat-core-rust/actions/workflows/ci.yml/badge.svg)](https://github.com/deltachat/deltachat-core-rust/actions/workflows/ci.yml)
[![Remote tests](https://github.com/deltachat/deltachat-core-rust/actions/workflows/remote_tests.yml/badge.svg)](https://github.com/deltachat/deltachat-core-rust/actions/workflows/remote_tests.yml)
[![CircleCI](https://circleci.com/gh/deltachat/deltachat-core-rust.svg?style=shield)](https://circleci.com/gh/deltachat/deltachat-core-rust/)
## Installing Rust and Cargo

View File

@@ -17,7 +17,7 @@ async fn address_book_benchmark(n: u32, read_count: u32) {
.collect::<Vec<String>>()
.join("");
Contact::add_address_book(&context, book).await.unwrap();
Contact::add_address_book(&context, &book).await.unwrap();
let query: Option<&str> = None;
for _ in 0..read_count {

View File

@@ -22,7 +22,7 @@ num-traits = "0.2.6"
serde_json = "1.0"
async-std = "1.9.0"
anyhow = "1.0.40"
thiserror = "1.0.14"
thiserror = "1.0.25"
rand = "0.7.3"
[features]

View File

@@ -13,6 +13,8 @@ use deltachat::contact::*;
use deltachat::context::*;
use deltachat::dc_receive_imf::*;
use deltachat::dc_tools::*;
use deltachat::error::Error;
use deltachat::export_chat::export_chat_to_zip;
use deltachat::imex::*;
use deltachat::location;
use deltachat::log::LogExt;
@@ -387,6 +389,7 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
protect <chat-id>\n\
unprotect <chat-id>\n\
delchat <chat-id>\n\
export-chat <chat-id> <destination-file>\n\
===========================Contact requests==\n\
decidestartchat <msg-id>\n\
decideblock <msg-id>\n\
@@ -1022,6 +1025,13 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
let chat_id = ChatId::new(arg1.parse()?);
chat_id.delete(&context).await?;
}
"export-chat" => {
ensure!(!arg1.is_empty(), "Argument <chat-id> missing.");
ensure!(!arg2.is_empty(), "Argument <destination file> missing.");
let chat_id = ChatId::new(arg1.parse()?);
// todo check if path is valid (dest dir exists) and ends in .zip
export_chat_to_zip(&context, chat_id, arg2).await;
}
"msginfo" => {
ensure!(!arg1.is_empty(), "Argument <msg-id> missing.");
let id = MsgId::new(arg1.parse()?);

View File

@@ -169,7 +169,7 @@ const DB_COMMANDS: [&str; 9] = [
"housekeeping",
];
const CHAT_COMMANDS: [&str; 34] = [
const CHAT_COMMANDS: [&str; 35] = [
"listchats",
"listarchived",
"chat",
@@ -204,6 +204,7 @@ const CHAT_COMMANDS: [&str; 34] = [
"protect",
"unprotect",
"delchat",
"export-chat",
];
const MESSAGE_COMMANDS: [&str; 6] = [
"listmsgs",

View File

@@ -1,15 +1,17 @@
import os
import sys
import platform
import subprocess
import sys
if __name__ == "__main__":
assert len(sys.argv) == 2
workspacedir = sys.argv[1]
arch = platform.machine()
for relpath in os.listdir(workspacedir):
if relpath.startswith("deltachat"):
p = os.path.join(workspacedir, relpath)
subprocess.check_call(
["auditwheel", "repair", p, "-w", workspacedir,
"--plat", "manylinux2014_x86_64"])
"--plat", "manylinux2014_" + arch])

View File

@@ -1033,6 +1033,33 @@ class TestOnlineAccount:
except queue.Empty:
pass # mark_seen_messages() has generated events before it returns
def test_moved_markseen(self, acfactory, lp):
"""Test that message already moved to DeltaChat folder is marked as seen."""
ac1 = acfactory.get_online_configuring_account(mvbox=True, config={"inbox_watch": "0"})
ac2 = acfactory.get_online_configuring_account()
acfactory.wait_configure_and_start_io([ac1, ac2])
ac1.set_config("bcc_self", "1")
ac1.direct_imap.idle_start()
ac1.create_chat(ac2).send_text("Hello!")
ac1.direct_imap.idle_check(terminate=True)
ac1.stop_io()
# Emulate moving of the message to DeltaChat folder by Sieve rule.
# mailcow server contains this rule by default.
ac1.direct_imap.conn.move(["*"], "DeltaChat")
ac1.direct_imap.select_folder("DeltaChat")
ac1.direct_imap.idle_start()
ac1.start_io()
ac1.direct_imap.idle_wait_for_seen()
ac1.direct_imap.idle_done()
fetch = list(ac1.direct_imap.conn.fetch("*", b'FLAGS').values())
flags = fetch[-1][b'FLAGS']
is_seen = b'\\Seen' in flags
assert is_seen
def test_message_override_sender_name(self, acfactory, lp):
ac1, ac2 = acfactory.get_two_online_accounts()
chat = acfactory.get_accepted_chat(ac1, ac2)
@@ -1071,10 +1098,10 @@ class TestOnlineAccount:
# We had so many problems with markseen, if in doubt, rather create another test, it can't harm.
ac1 = acfactory.get_online_configuring_account(move=mvbox_move, mvbox=mvbox_move)
ac2 = acfactory.get_online_configuring_account(move=mvbox_move, mvbox=mvbox_move)
acfactory.wait_configure_and_start_io()
acfactory.get_accepted_chat(ac1, ac2).send_text("hi")
msg = ac2._evtracker.wait_next_incoming_message()
acfactory.wait_configure_and_start_io()
# Do not send BCC to self, we only want to test MDN on ac1.
ac1.set_config("bcc_self", "0")
folder = "mvbox" if mvbox_move else "inbox"
ac1.direct_imap.select_config_folder(folder)
@@ -1082,6 +1109,9 @@ class TestOnlineAccount:
ac1.direct_imap.idle_start()
ac2.direct_imap.idle_start()
acfactory.get_accepted_chat(ac1, ac2).send_text("hi")
msg = ac2._evtracker.wait_next_incoming_message()
ac2.mark_seen_messages([msg])
ac1.direct_imap.idle_wait_for_seen() # Check that the mdn is marked as seen
@@ -2396,26 +2426,31 @@ class TestOnlineAccount:
assert received_reply.quoted_text == "hello"
assert received_reply.quote.id == out_msg.id
@pytest.mark.parametrize("folder,move,expected_destination,", [
("xyz", False, "xyz"), # Test that emails are recognized in a random folder but not moved
("xyz", True, "DeltaChat"), # ...emails are found in a random folder and moved to DeltaChat
("Spam", False, "INBOX") # ...emails are moved from the spam folder to the Inbox
@pytest.mark.parametrize("folder,move,expected_destination,inbox_watch,", [
("xyz", False, "xyz", "1"), # Test that emails are recognized in a random folder but not moved
("xyz", True, "DeltaChat", "1"), # ...emails are found in a random folder and moved to DeltaChat
("Spam", False, "INBOX", "1"), # ...emails are moved from the spam folder to the Inbox
("INBOX", False, "INBOX", "0"), # ...emails are found in the `Inbox` folder even if `inbox_watch` is "0"
])
# Testrun.org does not support the CREATE-SPECIAL-USE capability, which means that we can't create a folder with
# the "\Junk" flag (see https://tools.ietf.org/html/rfc6154). So, we can't test spam folder detection by flag.
def test_scan_folders(self, acfactory, lp, folder, move, expected_destination):
def test_scan_folders(self, acfactory, lp, folder, move, expected_destination, inbox_watch):
"""Delta Chat periodically scans all folders for new messages to make sure we don't miss any."""
variant = folder + "-" + str(move) + "-" + expected_destination
lp.sec("Testing variant " + variant)
ac1 = acfactory.get_online_configuring_account(move=move)
ac2 = acfactory.get_online_configuring_account()
ac1.set_config("inbox_watch", inbox_watch)
acfactory.wait_configure(ac1)
ac1.direct_imap.create_folder(folder)
acfactory.wait_configure_and_start_io()
# Wait until each folder was selected once and we are IDLEing:
ac1._evtracker.get_info_contains("INBOX: Idle entering wait-on-remote state")
if inbox_watch == "1":
ac1._evtracker.get_info_contains("INBOX: Idle entering wait-on-remote state")
else:
ac1._evtracker.get_info_contains("IMAP-fake-IDLE: no folder, waiting for interrupt")
ac1.stop_io()
# Send a message to ac1 and move it to the mvbox:
@@ -2432,7 +2467,10 @@ class TestOnlineAccount:
assert msg.text == "hello"
# Wait until the message was moved (if at all) and we are IDLEing again:
ac1._evtracker.get_info_contains("INBOX: Idle entering wait-on-remote state")
if inbox_watch == "1":
ac1._evtracker.get_info_contains("INBOX: Idle entering wait-on-remote state")
else:
ac1._evtracker.get_info_contains("IMAP-fake-IDLE: no folder, waiting for interrupt")
ac1.direct_imap.select_folder(expected_destination)
assert len(ac1.direct_imap.get_all_messages()) == 1
if folder != expected_destination:

View File

@@ -48,3 +48,7 @@ to avoid the relatively large download::
cd scripts # where all CI things are
docker build -t deltachat/coredeps docker-coredeps
docker build -t deltachat/doxygen docker-doxygen
Additionally, you can install qemu and build arm64 docker image:
apt-get install qemu binfmt-support qemu-user-static
docker build -t deltachat/coredeps-arm64 docker-coredeps-arm64

View File

@@ -0,0 +1,21 @@
FROM quay.io/pypa/manylinux2014_aarch64
# Configure ld.so/ldconfig and pkg-config
RUN echo /usr/local/lib64 > /etc/ld.so.conf.d/local.conf && \
echo /usr/local/lib >> /etc/ld.so.conf.d/local.conf
ENV PKG_CONFIG_PATH /usr/local/lib64/pkgconfig:/usr/local/lib/pkgconfig
# Install a recent Perl, needed to install the openssl crate
ADD deps/build_perl.sh /builder/build_perl.sh
RUN rm /usr/bin/perl
RUN mkdir tmp1 && cd tmp1 && bash /builder/build_perl.sh && cd .. && rm -r tmp1
ENV PIP_DISABLE_PIP_VERSION_CHECK 1
# Install python tools (auditwheels,tox, ...)
ADD deps/build_python.sh /builder/build_python.sh
RUN mkdir tmp1 && cd tmp1 && bash /builder/build_python.sh && cd .. && rm -r tmp1
# Install Rust
ADD deps/build_rust.sh /builder/build_rust.sh
RUN mkdir tmp1 && cd tmp1 && bash /builder/build_rust.sh && cd .. && rm -r tmp1

View File

@@ -0,0 +1,21 @@
#!/bin/bash
set -e -x
OPENSSL_VERSION=1.1.1a
OPENSSL_SHA256=fc20130f8b7cbd2fb918b2f14e2f429e109c31ddd0fb38fc5d71d9ffed3f9f41
curl -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz
echo "${OPENSSL_SHA256} openssl-${OPENSSL_VERSION}.tar.gz" | sha256sum -c -
tar xzf openssl-${OPENSSL_VERSION}.tar.gz
cd openssl-${OPENSSL_VERSION}
./config shared no-ssl2 no-ssl3 -fPIC --prefix=/usr/local
sed -i "s/^SHLIB_MAJOR=.*/SHLIB_MAJOR=200/" Makefile && \
sed -i "s/^SHLIB_MINOR=.*/SHLIB_MINOR=0.0/" Makefile && \
sed -i "s/^SHLIB_VERSION_NUMBER=.*/SHLIB_VERSION_NUMBER=200.0.0/" Makefile
make depend
make
make install_sw install_ssldirs
ldconfig -v | grep ssl

View File

@@ -0,0 +1,12 @@
#!/bin/bash
PERL_VERSION=5.30.0
# PERL_SHA256=7e929f64d4cb0e9d1159d4a59fc89394e27fa1f7004d0836ca0d514685406ea8
curl -O https://www.cpan.org/src/5.0/perl-${PERL_VERSION}.tar.gz
# echo "${PERL_SHA256} perl-${PERL_VERSION}.tar.gz" | sha256sum -c -
tar -xzf perl-${PERL_VERSION}.tar.gz
cd perl-${PERL_VERSION}
./Configure -de
make
make install

View File

@@ -0,0 +1,14 @@
#!/bin/bash
set -x -e
# we use the python3.6 environment as the base environment
/opt/python/cp36-cp36m/bin/pip install tox devpi-client auditwheel
pushd /usr/bin
ln -s /opt/_internal/cpython-3.6.*/bin/tox
ln -s /opt/_internal/cpython-3.6.*/bin/devpi
ln -s /opt/_internal/cpython-3.6.*/bin/auditwheel
popd

View File

@@ -0,0 +1,16 @@
#!/bin/bash
set -e -x
# Install Rust
#
# Path from https://forge.rust-lang.org/infra/other-installation-methods.html
#
# Avoid using rustup here as it depends on reading /proc/self/exe and
# has problems running under QEMU.
curl "https://static.rust-lang.org/dist/rust-1.52.1-$(uname -m)-unknown-linux-gnu.tar.gz" | tar xz
cd "rust-1.52.1-$(uname -m)-unknown-linux-gnu"
./install.sh --prefix=/usr --components=rustc,cargo,"rust-std-$(uname -m)-unknown-linux-gnu"
rustc --version
cd ..
rm -fr "rust-1.52.1-$(uname -m)-unknown-linux-gnu"

View File

@@ -5,7 +5,7 @@ RUN echo /usr/local/lib64 > /etc/ld.so.conf.d/local.conf && \
echo /usr/local/lib >> /etc/ld.so.conf.d/local.conf
ENV PKG_CONFIG_PATH /usr/local/lib64/pkgconfig:/usr/local/lib/pkgconfig
# Install a recent Perl, needed to install the openssl crate
# Install a recent Perl, needed to install the openssl crate
ADD deps/build_perl.sh /builder/build_perl.sh
RUN rm /usr/bin/perl
RUN mkdir tmp1 && cd tmp1 && bash /builder/build_perl.sh && cd .. && rm -r tmp1

View File

@@ -2,13 +2,13 @@
set -x -e
# we use the python3.5 environment as the base environment
/opt/python/cp35-cp35m/bin/pip install tox devpi-client auditwheel
# we use the python3.6 environment as the base environment
/opt/python/cp36-cp36m/bin/pip install tox devpi-client auditwheel
pushd /usr/bin
ln -s /opt/_internal/cpython-3.5.*/bin/tox
ln -s /opt/_internal/cpython-3.5.*/bin/devpi
ln -s /opt/_internal/cpython-3.5.*/bin/auditwheel
ln -s /opt/_internal/cpython-3.6.*/bin/tox
ln -s /opt/_internal/cpython-3.6.*/bin/devpi
ln -s /opt/_internal/cpython-3.6.*/bin/auditwheel
popd

View File

@@ -3,9 +3,9 @@
set -e -x
# Install Rust
curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.50.0-x86_64-unknown-linux-gnu -y
curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain "1.50.0-$(uname -m)-unknown-linux-gnu" -y
export PATH=/root/.cargo/bin:$PATH
rustc --version
# remove some 300-400 MB that we don't need for automated builds
rm -rf /root/.rustup/toolchains/1.50.0-x86_64-unknown-linux-gnu/share
rm -rf "/root/.rustup/toolchains/1.50.0-$(uname -m)-unknown-linux-gnu/share"

View File

@@ -15,6 +15,7 @@ git ls-files >.rsynclist
# we seem to need .git for setuptools_scm versioning
find .git >>.rsynclist
rsync --delete --files-from=.rsynclist -az ./ "$SSHTARGET:$BUILDDIR"
rsync --delete --files-from=.rsynclist -az ./ "$SSHTARGET:$BUILDDIR-arm64"
set +x
@@ -26,24 +27,41 @@ set +x
# everything is terminated/cleaned up and we have no orphaned
# useless still-running docker-containers consuming resources.
ssh $SSHTARGET bash -c "cat >$BUILDDIR/exec_docker_run" <<_HERE
for arch in "" "-arm64"; do
ssh $SSHTARGET bash -c "cat >${BUILDDIR}${arch}/exec_docker_run" <<_HERE
set +x -e
shopt -s huponexit
cd $BUILDDIR
cd ${BUILDDIR}${arch}
export DCC_NEW_TMP_EMAIL=$DCC_NEW_TMP_EMAIL
set -x
# run everything else inside docker
docker run -e DCC_NEW_TMP_EMAIL \
--rm -it -v \$(pwd):/mnt -w /mnt \
deltachat/coredeps scripts/run_all.sh
deltachat/coredeps${arch} scripts/run_all.sh
_HERE
done
echo "--- Running $CIRCLE_JOB remotely"
ssh -t $SSHTARGET bash "$BUILDDIR/exec_docker_run"
echo "--- Building aarch64 wheels"
ssh -o ServerAliveInterval=30 -t $SSHTARGET bash "$BUILDDIR-arm64/exec_docker_run"
echo "--- Building x86_64 wheels"
ssh -o ServerAliveInterval=30 -t $SSHTARGET bash "$BUILDDIR/exec_docker_run"
mkdir -p workspace
rsync -avz "$SSHTARGET:$BUILDDIR/python/.docker-tox/wheelhouse/*manylinux201*" workspace/wheelhouse/
rsync -avz "$SSHTARGET:$BUILDDIR/python/.docker-tox/dist/*" workspace/wheelhouse/
# Wheels
for arch in "" "-arm64"; do
rsync -avz "$SSHTARGET:$BUILDDIR${arch}/python/.docker-tox/wheelhouse/*manylinux201*" workspace/wheelhouse/
done
# Source packages
rsync -avz "$SSHTARGET:$BUILDDIR${arch}/python/.docker-tox/dist/*" workspace/wheelhouse/
# Documentation
rsync -avz "$SSHTARGET:$BUILDDIR/python/doc/_build/" workspace/py-docs

View File

@@ -19,14 +19,17 @@ export DCC_RS_TARGET=release
# Configure access to a base python and to several python interpreters
# needed by tox below.
export PATH=$PATH:/opt/python/cp35-cp35m/bin
export PATH=$PATH:/opt/python/cp36-cp36m/bin
export PYTHONDONTWRITEBYTECODE=1
pushd /bin
rm -f python3.5
ln -s /opt/python/cp35-cp35m/bin/python3.5
rm -f python3.6
ln -s /opt/python/cp36-cp36m/bin/python3.6
rm -f python3.7
ln -s /opt/python/cp37-cp37m/bin/python3.7
rm -f python3.8
ln -s /opt/python/cp38-cp38/bin/python3.8
rm -f python3.9
ln -s /opt/python/cp39-cp39/bin/python3.9
popd
pushd python
@@ -40,7 +43,7 @@ mkdir -p $TOXWORKDIR
# Note that the independent remote_tests_python step does all kinds of
# live-testing already.
unset DCC_NEW_TMP_EMAIL
tox --workdir "$TOXWORKDIR" -e py35,py36,py37,py38,auditwheels
tox --workdir "$TOXWORKDIR" -e py37,py38,py39,auditwheels
popd

View File

@@ -3986,4 +3986,33 @@ YEAAAAAA!.
.await,
);
}
#[async_std::test]
async fn test_dont_show_all_outgoing_msgs_in_self_chat() {
// Regression test for https://github.com/deltachat/deltachat-android/issues/1940:
// Some servers add a `Bcc: <Self>` header, which caused all outgoing messages to
// be shown in the self-chat.
let t = TestContext::new_alice().await;
dc_receive_imf(
&t,
b"Bcc: alice@example.com
Received: from [127.0.0.1]
Subject: s
Chat-Version: 1.0
Message-ID: <abcd@gmail.com>
To: <me@other.maildomain.com>
From: <alice@example.com>
Message content",
"Inbox",
1,
false,
)
.await
.unwrap();
let msg = t.get_last_msg().await;
assert_ne!(msg.chat_id, t.get_self_chat().await.id);
}
}

339
src/export_chat.rs Normal file
View File

@@ -0,0 +1,339 @@
//! Export chats module
//!
//! ## Export Format
//! The format of an exported chat is a zip file with the following structure:
//! ```text
//! ├── blobs/ # all files that are referenced by the chat
//! ├── msg_info/
//! │ └── [msg_id].txt # message info
//! ├── msg_source/
//! │ └── [msg_id].eml # email sourcecode of messages if availible¹
//! └── chat.json # chat info, messages and message authors
//! ```
//! ##### ¹ Saving Mime header
//! To save the mime header you need to have the config option [`SaveMimeHeaders`] enabled.
//! This option saves the mime headers on future messages. Normaly the original email source code is discarded to save space.
//! You can use the repl tool to do this job:
//! ```sh
//! $ cargo run --example repl --features=repl /path/to/account/db.sqlite
//! > set save_mime_headers 1
//! ```
//! [`SaveMimeHeaders`]: ../config/enum.Config.html#variant.SaveMimeHeaders
use crate::chat::*;
use crate::constants::Viewtype;
use crate::constants::DC_GCM_ADDDAYMARKER;
use crate::contact::*;
use crate::context::Context;
// use crate::error::Error;
use crate::dc_tools::time;
use crate::message::*;
use std::collections::HashMap;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
use zip::write::FileOptions;
use crate::location::Location;
use serde::Serialize;
#[derive(Debug)]
struct ExportChatResult {
chat_json: String,
// locations_geo_json: String,
message_ids: Vec<MsgId>,
referenced_blobs: Vec<String>,
}
pub async fn export_chat_to_zip(context: &Context, chat_id: ChatId, filename: &str) {
let res = export_chat_data(&context, chat_id).await;
let destination = std::path::Path::new(filename);
let pack_res = pack_exported_chat(&context, res, destination).await;
match &pack_res {
Ok(()) => println!("Exported chat successfully to {}", filename),
Err(err) => println!("Error {:?}", err),
};
}
async fn pack_exported_chat(
context: &Context,
artifact: ExportChatResult,
destination: &Path,
) -> zip::result::ZipResult<()> {
let file = std::fs::File::create(&destination).unwrap();
let mut zip = zip::ZipWriter::new(file);
zip.start_file("chat.json", Default::default())?;
zip.write_all(artifact.chat_json.as_bytes())?;
zip.add_directory("blobs/", Default::default())?;
let options = FileOptions::default();
for blob_name in artifact.referenced_blobs {
let path = context.get_blobdir().join(&blob_name);
// println!("adding file {:?} as {:?} ...", path, &blob_name);
zip.start_file(format!("blobs/{}", &blob_name), options)?;
let mut f = File::open(path)?;
let mut buffer = Vec::new();
f.read_to_end(&mut buffer)?;
zip.write_all(&*buffer)?;
buffer.clear();
}
zip.add_directory("msg_info/", Default::default())?;
zip.add_directory("msg_source/", Default::default())?;
for id in artifact.message_ids {
zip.start_file(format!("msg_info/{}.txt", id.to_u32()), options)?;
zip.write_all((get_msg_info(&context, id).await).as_bytes())?;
if let Some(mime_headers) = get_mime_headers(&context, id).await {
zip.start_file(format!("msg_source/{}.eml", id.to_u32()), options)?;
zip.write_all((mime_headers).as_bytes())?;
}
}
zip.finish()?;
Ok(())
}
#[derive(Serialize)]
struct ChatJSON {
chat_json_version: u8,
export_timestamp: i64,
name: String,
color: String,
profile_img: Option<String>,
contacts: HashMap<u32, ContactJSON>,
referenced_external_messages:Vec<ChatItemJSON>,
messages: Vec<ChatItemJSON>,
locations: Vec<Location>,
}
#[derive(Serialize)]
struct ContactJSON {
name: String,
email: String,
color: String,
profile_img: Option<String>,
}
#[derive(Serialize)]
struct FileReference {
name: String,
filesize: u64,
mime: String,
path: String,
}
#[derive(Serialize)]
struct Qoute {
quoted_text: String,
message_id: Option<u32>,
}
#[derive(Serialize)]
#[serde(tag = "type")]
enum ChatItemJSON {
Message {
id: u32,
author_id: u32, // from_id
view_type: Viewtype,
timestamp_sort: i64,
timestamp_sent: i64,
timestamp_rcvd: i64,
text: Option<String>,
attachment: Option<FileReference>,
location_id: Option<u32>,
is_info_message: bool,
show_padlock: bool,
state: MessageState,
is_forwarded: bool,
quote: Option<Qoute>
},
MessageError {
id: u32,
error: String,
},
DayMarker {
timestamp: i64,
},
}
impl ChatItemJSON {
pub async fn from_message(message: &Message, context: &Context) -> ChatItemJSON {
let msg_id = message.get_id();
ChatItemJSON::Message {
id: msg_id.to_u32(),
author_id: message.get_from_id(), // from_id
view_type: message.get_viewtype(),
timestamp_sort: message.timestamp_sort,
timestamp_sent: message.timestamp_sent,
timestamp_rcvd: message.timestamp_rcvd,
text: message.get_text(),
attachment: match message.get_file(context) {
Some(file) => Some(FileReference {
name: message.get_filename().unwrap_or_else(|| "".to_owned()),
filesize: message.get_filebytes(context).await,
mime: message.get_filemime().unwrap_or_else(|| "".to_owned()),
path: format!(
"blobs/{}",
file.file_name()
.unwrap_or_else(|| std::ffi::OsStr::new(""))
.to_str()
.unwrap()
),
}),
None => None,
},
location_id: match message.has_location() {
true => Some(message.location_id),
false => None,
},
is_info_message: message.is_info(),
show_padlock: message.get_showpadlock(),
state: message.get_state(),
is_forwarded: message.is_forwarded(),
quote: match message.quoted_text() {
Some(text) => match message.quoted_message(&context).await {
Ok(Some(msg)) => Some(Qoute {
quoted_text: text,
message_id: Some(msg.get_id().to_u32())
}),
Err(_) | Ok(None) => Some(Qoute {
quoted_text: text,
message_id: None
})
}
None => None
}
}
}
}
async fn export_chat_data(context: &Context, chat_id: ChatId) -> ExportChatResult {
let mut blobs = Vec::new();
let mut chat_author_ids = Vec::new();
// message_ids var is used for writing message info to files
let mut message_ids: Vec<MsgId> = Vec::new();
let mut message_json: Vec<ChatItemJSON> = Vec::new();
let mut referenced_external_messages: Vec<ChatItemJSON> = Vec::new();
for item in get_chat_msgs(context, chat_id, DC_GCM_ADDDAYMARKER, None).await {
if let Some(json_item) = match item {
ChatItem::Message { msg_id } => match Message::load_from_db(context, msg_id).await {
Ok(message) => {
let filename = message.get_filename();
if let Some(file) = filename {
// push referenced blobs (attachments)
blobs.push(file);
}
message_ids.push(message.id);
// populate contactid list
chat_author_ids.push(message.from_id);
if let Ok(Some(ex_msg)) = message.quoted_message(&context).await {
if ex_msg.get_chat_id() != chat_id {
// if external add it to the file
referenced_external_messages.push(ChatItemJSON::from_message(&ex_msg, &context).await)
// contacts don't need to be referenced, because these should only be private replies
}
}
Some(ChatItemJSON::from_message(&message, &context).await)
}
Err(error_message) => Some(ChatItemJSON::MessageError {
id: msg_id.to_u32(),
error: error_message.to_string(),
}),
},
ChatItem::DayMarker { timestamp } => Some(ChatItemJSON::DayMarker { timestamp }),
ChatItem::Marker1 => None,
} {
message_json.push(json_item)
}
}
// deduplicate contact list and load the contacts
chat_author_ids.sort();
chat_author_ids.dedup();
// load information about the authors
let mut chat_authors: HashMap<u32, ContactJSON> = HashMap::new();
chat_authors.insert(
0,
ContactJSON {
name: "Err: Contact not found".to_owned(),
email: "error@localhost".to_owned(),
profile_img: None,
color: "grey".to_owned(),
},
);
for author_id in chat_author_ids {
let contact = Contact::get_by_id(context, author_id).await;
if let Ok(c) = contact {
let profile_img_path: String;
if let Some(path) = c.get_profile_image(context).await {
profile_img_path = path
.file_name()
.unwrap_or_else(|| std::ffi::OsStr::new(""))
.to_str()
.unwrap()
.to_owned();
// push referenced blobs (avatars)
blobs.push(profile_img_path.clone());
} else {
profile_img_path = "".to_owned();
}
chat_authors.insert(
author_id,
ContactJSON {
name: c.get_display_name().to_owned(),
email: c.get_addr().to_owned(),
profile_img: match profile_img_path != "" {
true => Some(profile_img_path),
false => None,
},
color: format!("{:#}", c.get_color()), // TODO
},
);
}
}
// Load information about the chat
let chat: Chat = Chat::load_from_db(context, chat_id).await.unwrap();
let chat_avatar = match chat.get_profile_image(context).await {
Some(img) => {
let path = img
.file_name()
.unwrap_or_else(|| std::ffi::OsStr::new(""))
.to_str()
.unwrap()
.to_owned();
blobs.push(path.clone());
Some(format!("blobs/{}", path))
}
None => None,
};
let chat_json = ChatJSON {
chat_json_version: 1,
export_timestamp: time(),
name: chat.get_name().to_owned(),
color: format!("{:#}", chat.get_color(&context).await),
profile_img: chat_avatar,
contacts: chat_authors,
referenced_external_messages,
messages: message_json,
locations: crate::location::get_range(&context, chat_id, 0, 0, crate::dc_tools::time())
.await,
};
blobs.sort();
blobs.dedup();
ExportChatResult {
chat_json: serde_json::to_string(&chat_json).unwrap(),
message_ids,
referenced_blobs: blobs,
}
}

View File

@@ -25,7 +25,7 @@ impl Imap {
}
info!(context, "Starting full folder scan");
self.setup_handle(context).await?;
self.connect_configured(context).await?;
let session = self.session.as_mut();
let session = session.context("scan_folders(): IMAP No Connection established")?;
let folders: Vec<_> = session.list(Some(""), Some("*")).await?.collect().await;

View File

@@ -51,6 +51,7 @@ pub mod contact;
pub mod context;
mod e2ee;
pub mod ephemeral;
pub mod export_chat;
mod imap;
pub mod imex;
mod scheduler;

View File

@@ -16,9 +16,8 @@ use crate::message::{Message, MsgId};
use crate::mimeparser::SystemMessage;
use crate::param::Params;
use crate::stock_str;
/// Location record
#[derive(Debug, Clone, Default)]
use serde::Serialize;
#[derive(Debug, Clone, Default, Serialize)]
pub struct Location {
pub location_id: u32,
pub latitude: f64,

View File

@@ -1585,7 +1585,7 @@ fn get_attachment_filename(
/// Returned addresses are normalized and lowercased.
pub(crate) fn get_recipients(headers: &[MailHeader]) -> Vec<SingleInfo> {
get_all_addresses_from_header(headers, |header_key| {
header_key == "to" || header_key == "cc" || header_key == "bcc"
header_key == "to" || header_key == "cc"
})
}

View File

@@ -113,7 +113,6 @@ async fn decode_openpgp(context: &Context, qr: &str) -> Lot {
None
};
// what is up with that param name?
let name = if let Some(encoded_name) = param.get("n") {
let encoded_name = encoded_name.replace("+", "%20"); // sometimes spaces are encoded as `+`
match percent_decode_str(&encoded_name).decode_utf8() {