Files
chatmail-core/test-data/message/pdf_filename_simple.eml
Hocuri ebccdbbcb9 Improve onboarding by scanning all folders from time to time (#2067)
Start implementing #1994

TODO (in later PRs):

- Add a hint to the watch settings that all folders are fetched from time to time (to be done in the individual UIs)
- folder names are case-insensitive, so double-check that all comparisons are case-insensitive
- The `scan_folders.rs` file didn't get as large as I expected and it's probably not worth it having an extra file for it. But if there are no objections, I'll make another PR to rename it to `folders.rs` and also put into it `configure_folders()` from `imap/mod.rs` and `needs_move()` with all its tests from `message.rs`.

Done:

- Most mailboxes have a "Drafts" folder where constantly new emails appear but we don't actually want to show them, what do we do about this? The most reliable way to detect such messages that we found up to now is:
  If there is no `Received` header AND it's not in the `ConfiguredSentbox`, then ignore the email.
- before or after INBOX idle trigger a new "scan all folders for messages".  It does a "list folders" and then goes through all folders with select-statements, checking if "next-uid" was changed since checked last time.  This might be batchable but in any case should not consume a lot of traffic. We might debounce this scan activity to happen at most every N minutes 

- if next-uid changed for a folder, we "prefetch" and "fetch" DC-messages as as needed ("dc-messages" are not just those with "Chat-Version" headers, but can also be regular emails) 

- if we discover DC-messages in folders that have the "/Spam" flag (maybe excluding ContactRequests) we automatically move them to INBOX/DeltaChat folder to help  provider-spam-systems to regard this contact/mail as non-spam 

- for now, we do not change any user visible option, but introduce this "scan all" automatically and on top of what exists.   The DeltaChat folder-watching does not perform scan-all-folders (maybe with the exception to trigger scan-all also with DeltaChat if INBOX is not watched)

- Tests (except if you have ideas to improve them)
- all folders, their last uidvalidity, next-seen etc. are kept in a separate "imap-sync" sqlite table.  Maybe this can be used to streamline some of the "Sent" folder and "DeltaChat" folder detection code we already have. 

- We now also move self-sent messages from the Inbox to the Sent folder if `mvbox_move` is off, as this was very easy to do now. This way, we now behave more like a normal MUA if the user wants this.

FOR LATER PRs:

- maybe for the first 50 messages or so, we could reduce the IDLE-timeout (currently 23 minutes or so) to faster detect messages sent to non-inbox folders. However, on Android and iOS, we would likely trigger scan-all when the app moves to foreground, and so  it might not be neccessary to reduce the current idle-timeout at least for them.  We can leave this "faster discovery" question for the end, after we move to real-life testing. 

- (Later on, after the above works, we can consider heuristics on which folders to perform IDLE on, and remove the Watch-folder options (inbox, deltachat, sent). We tried to find a safe scheme for already doing it but failed to fine one, too many unknowns, also some questions regarding multi-device (you might have different settings with each of it, one moves, the other doesn't etc.) so we postponed this in favor of the above incremental suggestion.)




* Start implementing #1994

* Add debug logs, it seems like the SQL migration can go into another pr

* Let fetch_new_messages return whether there are new emails

* Code style

* Don't prefetch if there are no new emails

* clippy

* Even more debug logs

* If the folder was not newly selected, return always try to fetch as

uid_next is probably outdated

* Fix new bug

* Recognize spam folder

* if we discover DC-messages in folders that have the "/Spam" flag (excluding ContactRequests) we automatically move them to INBOX/DeltaChat folder to help provider-spam-systems to regard this contact/mail as non-spam

* Clippy, prioritize folder_meaning over folder_name_meaning

* Add a first test, for the first day after installation only debounce to 2s

* Start adding two tests (both of them fail)

* Don't abort folder scan if one folder fails

* More consts

* Replace bool return value by enum

* Split test up into multiple tests

* Print logs during rust tests

* Rust tests pass now

* .

* One of the Python tests passes now - reconfigure folders during scanning

* Make the last test pass - Delete emails in all folders when starting the test, not only inbox and mvbox

The problem had been that emails were left in the folder "xyz"

* lint

* DB migration (untested)

* Store uid_next in SQL instead of lastseen in a config

* Revert "If Inbox-watch is disabled and enabled again, do not fetch emails from in between"

all folders are always watched, anyway

* clippy, rm debug logs, comments

* Codestyle, comments

* fixing things again

* Fix another test: don't fetch from uid_next-1 but uid_next; make some {} to {:#} so that we can use `.context(...)`

* move self-sent, non-setupmessage chat messages to the Sent folder if `mvbox_move` is off

* comment

* Comments, make sure things work even if there is no uid_next

* Style

* Comments

* The rust test tested wrongly

* comments, small codestyle change

* Ignore emails that are probably only drafts

Most mailboxes have a "Drafts" folder where constantly new emails appear
but we don't actually want to show them.
So: If there is no Received header AND it's not in the ConfiguredSentbox,
then ignore the email.

Also: Add test.

* Fix occasional test failure, it was introduced as DC now moves messages from Inbox to Sent

* Add `Received` header to the rust tests

* After this PR we will always watch all folders and delete messages there if server_delete is enabled. So, for people who have server_delete on, disable it and add a hint to the devicechat

* comment, small fix

* link2xt's first review

* Use ON CONFLICT(FOLDER) DO to update and if it doesn't exist, then insert

Reason from link2xt: We had a problem with multiple peerstates inserted due to key fingerprint parsing error previously. With logic in Rust a similar problem can occur: an UPDATE can fail for reasons other than a conflict. PRIMARY KEY should ensure uniqueness in this case, but anyway.

* Remove two TODO statements, remove fetch_new_messages: ignoring uid {}, uid_next was {} log

* Next TODO: Make uidvalidity and uid_next DEFAULT 0

* rm two TODOs, Seems like we are not going to `exclude folders that are watched anyway` in this PR

* small tweak: Handle instants more carefully

* Add scan_all_folders_debounce_secs config for tests, set debounce to 60s (before it was just 2s during the first day)

* Don't use bold letters for the device message

* React to changes in the folders better

Before, if there was a configured Sent folder, but then it got
removed and replaced with another folder with a name meaning "Sent" but
without Sent flag, it would be ignored.

So, instead of checking against ConfiguredSentboxFolder,
create two Option variables at the beginning of the loop and replace
them with Some if it is None. At the end of the loop, store the new
values into ConfiguredSendboxFolder and ConfiguredSpamFolder, even if it
is None.

Also, derive some useful traits.

* move job: Return a meaningful error if server_folder is None instead of panicing

* small error-handling fix

* Fix test_fetch_existing() python test

Before, we sometimes got a race condition where scan_folders() sees that
there is a Sentbox and saves this info after we set the
ConfiguredSentbox to None and before the message is sent.

So, just expect that the message is moved to the sentbox.

* migration is 72 now

* rm 2 TODOs, Don't infinitely retry when dc_receive_imf() returns Err

* clippy: Remove glob imports

* Delete created folders at the beginning of tests

(some created folders made problems in the next tests because)

* Improve resetting accounts between tests
2021-01-13 14:09:51 +01:00

176 lines
11 KiB
Plaintext

Received: (Postfix, from userid 1000); Mon, 4 Dec 2006 14:51:39 +0100 (CET)\n\
To: dcuser@b44t.com
From: "Mail User" <mailuser@silverjuke.net>
Subject: Re: simple named pdf
Message-ID: <a91596c0-30a4-0622-1b95-625ef4af8c52@silverjuke.net>
Date: Sun, 15 Nov 2020 00:20:23 +0100
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:68.0)
Gecko/20100101 Thunderbird/68.10.0
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="------------E3735C3F321C73A6A1622476"
Content-Language: en-US
This is a multi-part message in MIME format.
--------------E3735C3F321C73A6A1622476
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
mail body
--------------E3735C3F321C73A6A1622476
Content-Type: application/pdf; x-mac-type="0"; x-mac-creator="0";
name="simple.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="simple.pdf"
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
MXQazacdpwX/V0NfFU48geYnHE+4nxAff6zJ8VhnrePRR1Y6Lj0y84hwfnb67CNlVt8L2Is9
0EI53HVWnHU8vb0Sb6FtmWl10HTT7KWZovkgTfq7h8QdNN3Yo2wUB/4CTQ/ZH3I9dO9Dxx7S
p++fuP/E/eLEkRNHhKfHL4wLWX+9I5V0OZKdqx02T01/kUfsN5Ab8q7sGKxb5QsNKI4BErp1
f7Njf2e94yZPeb+eNqwjQbPoEFvFXjElPiheEIuMe/y1jt00L/ln/ILiLy71mXsdve5e8fzs
JSXW7SRrO9M7J3aKO3z1jq7OjQ5zp6PT3flq59ud73UaBjrxSXr7nvZd8ImKr97tU3y1Tt+S
Lnt/laey34rmfovH3C8gFdoD/W7zrFkwmwfMh82iGVpBmKhCPZ7HE1N7+1yu7vNFs3u6VaP/
VhWPqnV9bFV271cNR1Xo339rYArxS8Ejx49D29JudW1fQA0tDXarUQIUBkwQYFk6VQVtwWw2
5+IDXS6Cx2gF15iLiAeyBSrM88GVxSzdUVmuhC4mUMCRVhfjEYHpIWkfyAJbGNNVUGLaWc0c
Vy4sHKg58N/FZYxCCmVuZHN0cmVhbQplbmRvYmoKCjYgMCBvYmoKNTY1NAplbmRvYmoKCjcg
MCBvYmoKPDwvVHlwZS9Gb250RGVzY3JpcHRvci9Gb250TmFtZS9CQUFBQUErTGliZXJhdGlv
blNlcmlmCi9GbGFncyA0Ci9Gb250QkJveFstNTQzIC0zMDMgMTI3OCA5ODJdL0l0YWxpY0Fu
Z2xlIDAKL0FzY2VudCA4OTEKL0Rlc2NlbnQgLTIxNgovQ2FwSGVpZ2h0IDk4MQovU3RlbVYg
ODAKL0ZvbnRGaWxlMiA1IDAgUgo+PgplbmRvYmoKCjggMCBvYmoKPDwvTGVuZ3RoIDI3MC9G
aWx0ZXIvRmxhdGVEZWNvZGU+PgpzdHJlYW0KeJxdkc9uwyAMxu88BcfuUIWkSbtKUaQqVaUc
9kfL9gAEnAxpAUTIIW8/MN0m7QD6GfuzPpus7a6dVj57dUb04OmotHSwmNUJoANMSpO8oFIJ
f4/wFjO3JAvafls8zJ0eTV2T7C3kFu82urtIM8ADyV6cBKf0RHcfbR/ifrX2C2bQnjLSNFTC
GPo8cfvMZ8hQte9kSCu/7YPkr+B9s0ALjPNkRRgJi+UCHNcTkJqxhta3W0NAy3+5nCXJMIpP
7kJpHkoZqw5N4AL5eI58SHyNXCKfWOQqvbeRj4mryCfkAmseU0/kM3JZRr4kPqKxu4NoMe7w
Z3QqVufC2LhonDdOqjT8/oU1NqrwfAOWToKDCmVuZHN0cmVhbQplbmRvYmoKCjkgMCBvYmoK
PDwvVHlwZS9Gb250L1N1YnR5cGUvVHJ1ZVR5cGUvQmFzZUZvbnQvQkFBQUFBK0xpYmVyYXRp
b25TZXJpZgovRmlyc3RDaGFyIDAKL0xhc3RDaGFyIDEwCi9XaWR0aHNbNzc3IDU1NiAyNzcg
Nzc3IDUwMCAyNzcgNDQzIDI1MCA1NTYgNzIyIDU1NiBdCi9Gb250RGVzY3JpcHRvciA3IDAg
UgovVG9Vbmljb2RlIDggMCBSCj4+CmVuZG9iagoKMTAgMCBvYmoKPDwvRjEgOSAwIFIKPj4K
ZW5kb2JqCgoxMSAwIG9iago8PC9Gb250IDEwIDAgUgovUHJvY1NldFsvUERGL1RleHRdCj4+
CmVuZG9iagoKMSAwIG9iago8PC9UeXBlL1BhZ2UvUGFyZW50IDQgMCBSL1Jlc291cmNlcyAx
MSAwIFIvTWVkaWFCb3hbMCAwIDU5NS4zMDM5MzcwMDc4NzQgODQxLjg4OTc2Mzc3OTUyOF0v
R3JvdXA8PC9TL1RyYW5zcGFyZW5jeS9DUy9EZXZpY2VSR0IvSSB0cnVlPj4vQ29udGVudHMg
MiAwIFI+PgplbmRvYmoKCjQgMCBvYmoKPDwvVHlwZS9QYWdlcwovUmVzb3VyY2VzIDExIDAg
UgovTWVkaWFCb3hbIDAgMCA1OTUgODQxIF0KL0tpZHNbIDEgMCBSIF0KL0NvdW50IDE+Pgpl
bmRvYmoKCjEyIDAgb2JqCjw8L1R5cGUvQ2F0YWxvZy9QYWdlcyA0IDAgUgovT3BlbkFjdGlv
blsxIDAgUiAvWFlaIG51bGwgbnVsbCAwXQovTGFuZyhkZS1ERSkKPj4KZW5kb2JqCgoxMyAw
IG9iago8PC9DcmVhdG9yPEZFRkYwMDU3MDA3MjAwNjkwMDc0MDA2NTAwNzI+Ci9Qcm9kdWNl
cjxGRUZGMDA0QzAwNjkwMDYyMDA3MjAwNjUwMDRGMDA2NjAwNjYwMDY5MDA2MzAwNjUwMDIw
MDAzNjAwMkUwMDMyPgovQ3JlYXRpb25EYXRlKEQ6MjAyMDExMTUwMDE4NTIrMDEnMDAnKT4+
CmVuZG9iagoKeHJlZgowIDE0CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwNjgxMyAwMDAw
MCBuIAowMDAwMDAwMDE5IDAwMDAwIG4gCjAwMDAwMDAyMTMgMDAwMDAgbiAKMDAwMDAwNjk4
MiAwMDAwMCBuIAowMDAwMDAwMjMzIDAwMDAwIG4gCjAwMDAwMDU5NzEgMDAwMDAgbiAKMDAw
MDAwNTk5MiAwMDAwMCBuIAowMDAwMDA2MTg3IDAwMDAwIG4gCjAwMDAwMDY1MjYgMDAwMDAg
biAKMDAwMDAwNjcyNiAwMDAwMCBuIAowMDAwMDA2NzU4IDAwMDAwIG4gCjAwMDAwMDcwODEg
MDAwMDAgbiAKMDAwMDAwNzE3OCAwMDAwMCBuIAp0cmFpbGVyCjw8L1NpemUgMTQvUm9vdCAx
MiAwIFIKL0luZm8gMTMgMCBSCi9JRCBbIDxEMTk1MUJGRUE4RDI0QzlCNjkyREM2RUVENUI0
MEJFOT4KPEQxOTUxQkZFQThEMjRDOUI2OTJEQzZFRUQ1QjQwQkU5PiBdCi9Eb2NDaGVja3N1
bSAvNDA4Qjg0MEU0NkYxNzk0MDhCNzhDRDlERDE4MkM5NjEKPj4Kc3RhcnR4cmVmCjczNTMK
JSVFT0YK
--------------E3735C3F321C73A6A1622476--