diff options
author | Anna Larch <anna@nextcloud.com> | 2021-02-25 11:30:36 +0300 |
---|---|---|
committer | Anna Larch <anna@nextcloud.com> | 2021-02-26 16:45:01 +0300 |
commit | 4cc2dd73fdddabf9299ca91464023d7b706a1e41 (patch) | |
tree | aea66411757fdf5519ce60c41a7717b5078a22e1 /lib | |
parent | 649d9b1f384cb088db508a95eeae21dc949617e4 (diff) |
Save important flag to IMAP if permflags enabled
Signed-off-by: Anna Larch <anna@nextcloud.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Db/MessageMapper.php | 2 | ||||
-rw-r--r-- | lib/Listener/NewMessageClassificationListener.php | 7 | ||||
-rw-r--r-- | lib/Model/IMAPMessage.php | 5 | ||||
-rw-r--r-- | lib/Service/MailManager.php | 53 |
4 files changed, 62 insertions, 5 deletions
diff --git a/lib/Db/MessageMapper.php b/lib/Db/MessageMapper.php index e83d08961..81f1967a7 100644 --- a/lib/Db/MessageMapper.php +++ b/lib/Db/MessageMapper.php @@ -333,6 +333,7 @@ class MessageMapper extends QBMapper { ->set('flag_junk', $query->createParameter('flag_junk')) ->set('flag_notjunk', $query->createParameter('flag_notjunk')) ->set('flag_mdnsent', $query->createParameter('flag_mdnsent')) + ->set('flag_important', $query->createParameter('flag_important')) ->set('updated_at', $query->createNamedParameter($this->timeFactory->getTime())) ->where($query->expr()->andX( $query->expr()->eq('uid', $query->createParameter('uid')), @@ -356,6 +357,7 @@ class MessageMapper extends QBMapper { $query->setParameter('flag_junk', $message->getFlagJunk(), IQueryBuilder::PARAM_BOOL); $query->setParameter('flag_notjunk', $message->getFlagNotjunk(), IQueryBuilder::PARAM_BOOL); $query->setParameter('flag_mdnsent', $message->getFlagMdnsent(), IQueryBuilder::PARAM_BOOL); + $query->setParameter('flag_important', $message->getFlagImportant(), IQueryBuilder::PARAM_BOOL); $query->execute(); } diff --git a/lib/Listener/NewMessageClassificationListener.php b/lib/Listener/NewMessageClassificationListener.php index 365251883..56585730c 100644 --- a/lib/Listener/NewMessageClassificationListener.php +++ b/lib/Listener/NewMessageClassificationListener.php @@ -67,11 +67,16 @@ class NewMessageClassificationListener implements IEventListener { } } + // if the message is already flagged as important, we won't classify it again. + $messages = array_filter($event->getMessages(), function ($message) { + return ($message->getFlagImportant() === false); + }); + try { $predictions = $this->classifier->classifyImportance( $event->getAccount(), $event->getMailbox(), - $event->getMessages() + $messages ); foreach ($event->getMessages() as $message) { diff --git a/lib/Model/IMAPMessage.php b/lib/Model/IMAPMessage.php index 46f00da08..bd8437e72 100644 --- a/lib/Model/IMAPMessage.php +++ b/lib/Model/IMAPMessage.php @@ -129,6 +129,7 @@ class IMAPMessage implements IMessage, JsonSerializable { } /** + * @deprecated Seems unused * @return array */ public function getFlags(): array { @@ -142,10 +143,12 @@ class IMAPMessage implements IMessage, JsonSerializable { 'forwarded' => in_array(Horde_Imap_Client::FLAG_FORWARDED, $flags), 'hasAttachments' => $this->hasAttachments($this->fetch->getStructure()), 'mdnsent' => in_array(Horde_Imap_Client::FLAG_MDNSENT, $flags, true), + 'important' => in_array('$important', $flags, true) ]; } /** + * @deprecated Seems unused * @param string[] $flags * * @throws Exception @@ -691,7 +694,7 @@ class IMAPMessage implements IMessage, JsonSerializable { in_array('junk', $flags, true) ); $msg->setFlagNotjunk(in_array(Horde_Imap_Client::FLAG_NOTJUNK, $flags, true)); - $msg->setFlagImportant(false); + $msg->setFlagImportant(in_array('$important', $flags, true)); $msg->setFlagAttachments(false); $msg->setFlagMdnsent(in_array(Horde_Imap_Client::FLAG_MDNSENT, $flags, true)); diff --git a/lib/Service/MailManager.php b/lib/Service/MailManager.php index 96c12b5b0..d37278477 100644 --- a/lib/Service/MailManager.php +++ b/lib/Service/MailManager.php @@ -26,6 +26,7 @@ namespace OCA\Mail\Service; use Horde_Imap_Client; use Horde_Imap_Client_Exception; use Horde_Imap_Client_Exception_NoSupportExtension; +use Horde_Imap_Client_Socket; use OCA\Mail\Account; use OCA\Mail\Contracts\IMailManager; use OCA\Mail\Db\Mailbox; @@ -386,10 +387,13 @@ class MailManager implements IMailManager { } // Only send system flags to the IMAP server as other flags might not be supported - $imapFlags = self::ALLOWED_FLAGS[$flag] ?? []; + $imapFlags = $this->filterFlags($account, $flag, $mailbox); try { foreach ($imapFlags as $imapFlag) { - if ($value) { + if (empty($imapFlag) === true) { + continue; + } + if ($value === true) { $this->imapMessageMapper->addFlag($client, $mb, $uid, $imapFlag); } else { $this->imapMessageMapper->removeFlag($client, $mb, $uid, $imapFlag); @@ -509,7 +513,50 @@ class MailManager implements IMailManager { * @param Message $message * @return array[] */ - public function getMailAttachments(Account $account, Mailbox $mailbox, Message $message) : array { + public function getMailAttachments(Account $account, Mailbox $mailbox, Message $message): array { return $this->imapMessageMapper->getAttachments($this->imapClientFactory->getClient($account), $mailbox->getName(), $message->getUid()); } + + /** + * Filter out IMAP flags that aren't supported by the client server + * + * @param Horde_Imap_Client_Socket $client + * @param string $flag + * @param string $mailbox + * @return array + */ + public function filterFlags(Account $account, string $flag, string $mailbox): array { + // check for RFC server flags + if (array_key_exists($flag, self::ALLOWED_FLAGS) === true) { + return self::ALLOWED_FLAGS[$flag]; + } + + // Only allow flag setting if IMAP supports Permaflags + // @TODO check if there are length & char limits on permflags + if ($this->isPermflagsEnabled($account, $mailbox) === true) { + return ["$" . $flag]; + } + return []; + } + + /** + * Check IMAP server for support for PERMANENTFLAGS + * + * @param Account $account + * @param string $mailbox + * @return boolean + */ + public function isPermflagsEnabled(Account $account, string $mailbox): bool { + $client = $this->imapClientFactory->getClient($account); + try { + $capabilities = $client->status($mailbox, Horde_Imap_Client::STATUS_PERMFLAGS); + } catch (Horde_Imap_Client_Exception $e) { + throw new ServiceException( + "Could not get message flag options from IMAP: " . $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + return (is_array($capabilities) === true && array_key_exists('permflags', $capabilities) === true && in_array("\*", $capabilities['permflags'], true) === true); + } } |