In contrast to get_config_delete_server_after(), value 1 does not mean
"delete at once", because it does not make sense to delete messages
immediately after receivning them.
MarkseenMdnOnImap stored server folder and UID which are never updated
by update_server_uid. Now hidden entries are created for MDNs, so they
should be handled as ordinary messages.
Sometimes message deletion job marks message as unlinked without
actually deleting it. It is possible if the message was already moved
into another folder, possibly by second device, but not detected there
yet. It should be detected later in the other folder, and the
server_uid in the database should be set.
Since introduction of add_imap_deletion_jobs() any expired message
record will be marked as unlinked eventually, because another message
deletion job will be scheduled even if update_server_uid() resurrects
the message once.
This may result in messages not being deleted. Optimization and
traffic-saving is postponed for later, one idea is to optimize message
deletion to avoid checking if Message-ID on the server matches
Message-ID in the database.
If job returns Status::Finished, it will be deleted. Then
add_imap_deletion_jobs will recreate it immediately if the message is
expired. To actually backoff the job, we should postpone it instead of
removing.
This is to avoid creating thousands of jobs when user enables
"delete_server_after" setting for the first time.
If device is offline for more than 2 weeks, some messages may not be
deleted.
When "delete_server_after" setting is configured, postponed
DeleteMsgOnImap jobs are created for incoming messages.
This commit adds job::add_imap_deletion_jobs function which creates
DeleteMsgOnImap jobs right before performing IMAP jobs. This way even
messages that expired when the setting was disabled are going to be
deleted.
Job creation on message reception is unnecessary now, and even harmful
because it will create jobs with an expiration time which may later be
reduced. It is planned to be removed in following commits.
Now 0 means "never delete", 1 means "delete at once" and other values
indicate the number of seconds after which them message should be
deleted from the server.
Configuration value interpretation is moved into
Context.get_config_delete_server_after() function.
At least one entry is required for DeleteMsgOnImap job. Additionally,
adding a hidden entry makes it possible to avoid redownloading the
message if it gets a new UID on the server.
DeleteMsgOnImap deletes files from the server only when the last part
is deleted. Removing only the first part of the hidden or trashed
message does not result in message deletion.
Currently only trashed or hidden messages are deleted by
DeleteMsgOnImap, so it is safe to remove database records.
It is planned to delete messages on IMAP server after
user-configurable time to cleanup the server even for messages
displayed in chats. For such messages, we unlink them from the
Message-ID, but keep the database record to display them.
Mutable UID reference is removed. Instead, ImapActionResult is
returned immediately.
If message has changed and UID does not correspond to expected
message, ImapActionResult::Failed is returned. Temprorary IMAP errors
result in ImapActionResult::RetryLater.
On the job side, ImapActionResult::RetryLater does not result in
immediate job retry anymore. Instead, job is retried with a backoff.
In addition to moving the message into trash chat, this function
removes message text to make sure the message does not remain in the
database. Only the information necessary to delete message from the
server and avoid redownloading it should be kept, such as Message-Id
and IMAP UID.
CString::yolo was still used in the ffi, this was an unsafe
transitional thing. To remove it there were two choices: 1. make
errors in creating CStrings hard errors or 2. try and be as lenient as
possible. Given the to_string_lossy() convention adopted in the ffi
this choose the lenient option and simply skips over embedded null
bytes, leaving the rest of the strings intact.
Thus now CString::new_lossy(). It's only used for .strdup() however
so no longer a public trait.
This also cleans up the public visibility of things in the strings.rs
file:
- Rename StrExt/OptStrExt traits to what they actually do: provide
.strdup() -> Strdup/OptStrdup.
- dc_strdup() should be an implementation detail, replace all usages
with Strdup.strdup() method.
- Only allow visibility inside the crate for all things.
- Reduce visibility to only the module for things not used in lib.rs.