From fa7ec4e09e940ec806d618949bea7ed10a0dc5fe Mon Sep 17 00:00:00 2001 From: Anna Larch Date: Thu, 11 Aug 2022 12:44:18 +0200 Subject: [PATCH] fixup! Add imip processing --- lib/Db/MessageMapper.php | 1 - lib/Model/IMAPMessage.php | 10 +------ lib/Service/IMipService.php | 54 +++++++++++++++++++++++-------------- lib/Service/MailManager.php | 6 ++--- 4 files changed, 38 insertions(+), 33 deletions(-) diff --git a/lib/Db/MessageMapper.php b/lib/Db/MessageMapper.php index fab4e8fc83..ddb20e7608 100644 --- a/lib/Db/MessageMapper.php +++ b/lib/Db/MessageMapper.php @@ -549,7 +549,6 @@ public function updateImipData(Message ...$messages): array { $query->setParameter('imip_message', $message->isImipMessage(), IQueryBuilder::PARAM_BOOL); $query->setParameter('imip_error', $message->isImipError(), IQueryBuilder::PARAM_BOOL); $query->setParameter('imip_processed', $message->isImipProcessed(), IQueryBuilder::PARAM_BOOL); - $query->execute(); } diff --git a/lib/Model/IMAPMessage.php b/lib/Model/IMAPMessage.php index a56aef7e25..078c0dc67e 100644 --- a/lib/Model/IMAPMessage.php +++ b/lib/Model/IMAPMessage.php @@ -194,14 +194,6 @@ private function getRawReferences(): string { return $references->value_single; } - private function isImipMessage(): bool { - $schedulingHeader = $this->fetch->getEnvelope(); // how can I find out if this has a body part 'ics\text' and a method? - if($schedulingHeader === null) { - return false; - } -// return true; - } - private function getRawInReplyTo(): string { return $this->fetch->getEnvelope()->in_reply_to; } @@ -803,7 +795,7 @@ public function toDbMessage(int $mailboxId, MailAccount $account): Message { $msg->setFlagImportant(in_array('$important', $flags, true) || in_array('$labelimportant', $flags, true) || in_array(Tag::LABEL_IMPORTANT, $flags, true)); $msg->setFlagAttachments(false); $msg->setFlagMdnsent(in_array(Horde_Imap_Client::FLAG_MDNSENT, $flags, true)); - if($this->isImipMessage()) { + if(!empty($this->scheduling)) { $msg->setImipMessage(true); } diff --git a/lib/Service/IMipService.php b/lib/Service/IMipService.php index 70139018d3..65b6e58738 100644 --- a/lib/Service/IMipService.php +++ b/lib/Service/IMipService.php @@ -32,6 +32,7 @@ use OCA\Mail\Db\Message; use OCA\Mail\Db\MessageMapper; use OCA\Mail\Exception\ServiceException; +use OCA\Mail\Model\IMAPMessage; use OCP\AppFramework\Db\DoesNotExistException; use OCP\Calendar\IManager; use Psr\Log\LoggerInterface; @@ -68,13 +69,13 @@ public function process(): void { return $message->getMailboxId(); }, $messages)); - $mailboxes = array_combine($mailboxIds, array_map(function (int $mailboxId) { + $mailboxes = array_map(function (int $mailboxId) { try { return $this->mailboxMapper->findById($mailboxId); } catch (DoesNotExistException | ServiceException $e) { return null; } - }, $mailboxIds)); + }, $mailboxIds); // Collect all accounts in memory $accountIds = array_unique(array_map(function (Mailbox $mailbox) { @@ -89,33 +90,48 @@ public function process(): void { } }, $accountIds)); - // @todo loop through mailboxes with associated messages instead - foreach ($messages as $message) { - /** @var Mailbox $mailbox */ - $mailbox = $mailboxes[$message->getMailboxId()]; - if( $mailbox === null ) { - $message->setImipProcessed(true); // Silently drop from passing to DAV and mark as processed, so we won't run into this message again. - continue; - } - + /** @var Mailbox $mailbox */ + foreach ($mailboxes as $mailbox) { /** @var Account $account */ $account = $accounts[$mailbox->getAccountId()]; + $filteredMessages = array_filter($messages, function ($message) use ($mailbox) { + return $message->getMailboxId() === $mailbox->getId(); + }); + + if (empty($filteredMessages)) { + continue; + } // Check for accounts or mailboxes that no longer exist, - // no processing for drafts and sent items - if ($account === null || $mailbox->isSpecialUse("sent") || $mailbox->isSpecialUse("drafts")) { // does this need more use cases? Also probably won't work? @todo - $message->setImipProcessed(true); // Silently drop from passing to DAV and mark as processed, so we won't run into this message again. + // no processing for drafts, sent items, junk or trash + if ($account === null + || $mailbox->isSpecialUse('sent') + || $mailbox->isSpecialUse('drafts') + || $mailbox->isSpecialUse('junk') + || $mailbox->isSpecialUse('trash') + ) { + array_map(function ($message) { + $message->setImipProcessed(true); + }, $filteredMessages); // Silently drop from passing to DAV and mark as processed, so we won't run into these messages again. + $this->messageMapper->updateImipData(...$filteredMessages); continue; } try { - $imapMessages = $this->mailManager->getImapMessagesForScheduleProcessing($account, $mailbox, [$message->getUid()]); // UIDS should return an ordered result, no? @todo + $imapMessages = $this->mailManager->getImapMessagesForScheduleProcessing($account, $mailbox, array_map(function ($message) { + return $message->getUid(); + }, $filteredMessages), true); } catch (ServiceException $e) { $this->logger->error('Could not get IMAP messages form IMIP server', ['exception' => $e]); return; } - foreach($imapMessages as $imapMessage) { + + + foreach ($filteredMessages as $message) { + $imapMessage = array_filter($imapMessages, function (IMAPMessage $imapMessage) use ($message) { + return $message->getUid() === $imapMessage->getUid(); + }); if (empty($imapMessage->scheduling[0])) { // No scheduling info, maybe the DB is wrong $message->setImipError(true); @@ -125,7 +141,7 @@ public function process(): void { $principalUri = 'principals/users/' . $account->getUserId(); $sender = $imapMessage->getFrom()->first()->getEmail(); $recipient = $account->getEmail(); - foreach($imapMessage->scheduling as $schedulingInfo) { // an IMAP message could contain more than one iMIP object + foreach ($imapMessage->scheduling as $schedulingInfo) { // an IMAP message could contain more than one iMIP object if ($schedulingInfo['method'] === 'REPLY') { $processed = $this->calendarManager->handleIMipReply($principalUri, $sender, $recipient, $schedulingInfo['contents']); $message->setImipProcessed($processed); @@ -141,10 +157,8 @@ public function process(): void { $message->setImipError(!$processed); } } - } - + $this->messageMapper->updateImipData(...$filteredMessages); } - $this->messageMapper->updateImipData(...$messages); } } diff --git a/lib/Service/MailManager.php b/lib/Service/MailManager.php index 21bd04bafa..19f64a3daa 100644 --- a/lib/Service/MailManager.php +++ b/lib/Service/MailManager.php @@ -198,21 +198,21 @@ public function getImapMessage(Account $account, /** * @param Account $account * @param Mailbox $mailbox - * @param int[] $uid + * @param int[] $uids * @param bool $loadBody * @return IMAPMessage[] * @throws ServiceException */ public function getImapMessagesForScheduleProcessing(Account $account, Mailbox $mailbox, - array $uid, + array $uids, bool $loadBody = false): array { $client = $this->imapClientFactory->getClient($account); try { return $this->imapMessageMapper->findByIds( $client, $mailbox->getName(), - new Horde_Imap_Client_Ids($uid), + new Horde_Imap_Client_Ids($uids), true ); } catch (Horde_Imap_Client_Exception|DoesNotExistException $e) {