Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/mail.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Larch <anna@nextcloud.com>2021-03-04 19:31:21 +0300
committerChristoph Wurst <christoph@winzerhof-wurst.at>2021-03-22 20:06:02 +0300
commit83a58623b116cd3f8c79f751a3df5963b3392692 (patch)
tree8f9660e75ea8748057e752c4f1573e3c618b5b85 /lib/Service
parentf27fb61c0fe15ef6a278a40d7774cde4b7c748b8 (diff)
Add tagging to messages
Signed-off-by: Anna Larch <anna@nextcloud.com>
Diffstat (limited to 'lib/Service')
-rw-r--r--lib/Service/MailManager.php113
-rw-r--r--lib/Service/Search/Flag.php4
-rw-r--r--lib/Service/SetupService.php16
-rw-r--r--lib/Service/Sync/ImapToDbSynchronizer.php14
4 files changed, 114 insertions, 33 deletions
diff --git a/lib/Service/MailManager.php b/lib/Service/MailManager.php
index d37278477..782946e6a 100644
--- a/lib/Service/MailManager.php
+++ b/lib/Service/MailManager.php
@@ -23,34 +23,36 @@ declare(strict_types=1);
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\Db\Tag;
+use OCA\Mail\Folder;
use OCA\Mail\Account;
-use OCA\Mail\Contracts\IMailManager;
+use Horde_Imap_Client;
+use function array_map;
use OCA\Mail\Db\Mailbox;
-use OCA\Mail\Db\MailboxMapper;
use OCA\Mail\Db\Message;
-use OCA\Mail\Db\MessageMapper as DbMessageMapper;
-use OCA\Mail\Events\BeforeMessageDeletedEvent;
+use function array_values;
+use OCA\Mail\Db\TagMapper;
+use Psr\Log\LoggerInterface;
+use Horde_Imap_Client_Socket;
+use OCA\Mail\Db\MailboxMapper;
+use OCA\Mail\IMAP\FolderStats;
+use OCA\Mail\IMAP\MailboxSync;
+use OCA\Mail\IMAP\FolderMapper;
+use OCA\Mail\Model\IMAPMessage;
+use Horde_Imap_Client_Exception;
+use OCA\Mail\Contracts\IMailManager;
+use OCA\Mail\IMAP\IMAPClientFactory;
+use OCA\Mail\Exception\ClientException;
use OCA\Mail\Events\MessageDeletedEvent;
use OCA\Mail\Events\MessageFlaggedEvent;
-use OCA\Mail\Exception\ClientException;
use OCA\Mail\Exception\ServiceException;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCA\Mail\Events\BeforeMessageDeletedEvent;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCA\Mail\Db\MessageMapper as DbMessageMapper;
+use Horde_Imap_Client_Exception_NoSupportExtension;
use OCA\Mail\Exception\TrashMailboxNotSetException;
-use OCA\Mail\Folder;
-use OCA\Mail\IMAP\FolderMapper;
-use OCA\Mail\IMAP\FolderStats;
-use OCA\Mail\IMAP\IMAPClientFactory;
-use OCA\Mail\IMAP\MailboxSync;
use OCA\Mail\IMAP\MessageMapper as ImapMessageMapper;
-use OCA\Mail\Model\IMAPMessage;
-use OCP\AppFramework\Db\DoesNotExistException;
-use OCP\EventDispatcher\IEventDispatcher;
-use Psr\Log\LoggerInterface;
-use function array_map;
-use function array_values;
class MailManager implements IMailManager {
@@ -86,8 +88,12 @@ class MailManager implements IMailManager {
/** @var DbMessageMapper */
private $dbMessageMapper;
+ /** @var TagMapper */
+ private $tagMapper;
+
/** @var IEventDispatcher */
private $eventDispatcher;
+
/**
* @var LoggerInterface
*/
@@ -100,7 +106,8 @@ class MailManager implements IMailManager {
ImapMessageMapper $messageMapper,
DbMessageMapper $dbMessageMapper,
IEventDispatcher $eventDispatcher,
- LoggerInterface $logger) {
+ LoggerInterface $logger,
+ TagMapper $tagMapper) {
$this->imapClientFactory = $imapClientFactory;
$this->mailboxMapper = $mailboxMapper;
$this->mailboxSync = $mailboxSync;
@@ -109,6 +116,7 @@ class MailManager implements IMailManager {
$this->dbMessageMapper = $dbMessageMapper;
$this->eventDispatcher = $eventDispatcher;
$this->logger = $logger;
+ $this->tagMapper = $tagMapper;
}
public function getMailbox(string $uid, int $id): Mailbox {
@@ -393,7 +401,7 @@ class MailManager implements IMailManager {
if (empty($imapFlag) === true) {
continue;
}
- if ($value === true) {
+ if ($value) {
$this->imapMessageMapper->addFlag($client, $mb, $uid, $imapFlag);
} else {
$this->imapMessageMapper->removeFlag($client, $mb, $uid, $imapFlag);
@@ -420,6 +428,50 @@ class MailManager implements IMailManager {
}
/**
+ * Tag (flag) a message on IMAP
+ *
+ * @param Account $account
+ * @param string $mailbox
+ * @param integer $uid
+ * @param Tag $tag
+ * @param boolean $value
+ * @return void
+ *
+ * @uses
+ *
+ * @link https://github.com/nextcloud/mail/issues/25
+ */
+ public function tagMessage(Account $account, string $mailbox, Message $message, Tag $tag, bool $value): void {
+ $client = $this->imapClientFactory->getClient($account);
+ try {
+ $mb = $this->mailboxMapper->find($account, $mailbox);
+ } catch (DoesNotExistException $e) {
+ throw new ClientException("Mailbox $mailbox does not exist", 0, $e);
+ }
+ if ($this->isPermflagsEnabled($account, $mailbox) === true) {
+ try {
+ if ($value) {
+ // imap keywords and flags work the same way
+ $this->imapMessageMapper->addFlag($client, $mb, $message->getUid(), $tag->getImapLabel());
+ } else {
+ $this->imapMessageMapper->removeFlag($client, $mb, $message->getUid(), $tag->getImapLabel());
+ }
+ } catch (Horde_Imap_Client_Exception $e) {
+ throw new ServiceException(
+ "Could not set message keyword on IMAP: " . $e->getMessage(),
+ (int) $e->getCode(),
+ $e
+ );
+ }
+ }
+ if ($value) {
+ $this->tagMapper->tagMessage($tag, $message->getMessageId(), $account->getUserId());
+ } else {
+ $this->tagMapper->untagMessage($tag, $message->getMessageId());
+ }
+ }
+
+ /**
* @param Account $account
*
* @return Quota|null
@@ -518,6 +570,21 @@ class MailManager implements IMailManager {
}
/**
+ * @param string $imapLabel
+ * @param string $userId
+ * @return Tag
+ * @throws DoesNotExistException
+ */
+ public function getTagByImapLabel(string $imapLabel, string $userId): Tag {
+ try {
+ return $this->tagMapper->getTagByImapLabel($imapLabel, $userId);
+ } catch (DoesNotExistException $e) {
+ throw new ClientException('Unknow Tag', (int)$e->getCode(), $e);
+ }
+ }
+
+
+ /**
* Filter out IMAP flags that aren't supported by the client server
*
* @param Horde_Imap_Client_Socket $client
@@ -534,7 +601,7 @@ class MailManager implements IMailManager {
// 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 [$flag];
}
return [];
}
diff --git a/lib/Service/Search/Flag.php b/lib/Service/Search/Flag.php
index 79294813a..491a63aca 100644
--- a/lib/Service/Search/Flag.php
+++ b/lib/Service/Search/Flag.php
@@ -26,6 +26,7 @@ declare(strict_types=1);
namespace OCA\Mail\Service\Search;
use Horde_Imap_Client;
+use OCA\Mail\Db\Tag;
/**
* @psalm-immutable
@@ -34,7 +35,8 @@ class Flag {
public const ANSWERED = Horde_Imap_Client::FLAG_ANSWERED;
public const SEEN = Horde_Imap_Client::FLAG_SEEN;
public const FLAGGED = Horde_Imap_Client::FLAG_FLAGGED;
- public const IMPORTANT = '\\important';
+ /** @deprecated */
+ public const IMPORTANT = Tag::LABEL_IMPORTANT;
public const DELETED = Horde_Imap_Client::FLAG_DELETED;
/** @var string */
diff --git a/lib/Service/SetupService.php b/lib/Service/SetupService.php
index ffd6146ac..78b423425 100644
--- a/lib/Service/SetupService.php
+++ b/lib/Service/SetupService.php
@@ -31,6 +31,7 @@ use Horde_Mail_Exception;
use Horde_Mail_Transport_Smtphorde;
use OCA\Mail\Account;
use OCA\Mail\Db\MailAccount;
+use OCA\Mail\Db\TagMapper;
use OCA\Mail\Exception\CouldNotConnectException;
use OCA\Mail\Exception\ServiceException;
use OCA\Mail\IMAP\IMAPClientFactory;
@@ -56,21 +57,26 @@ class SetupService {
/** @var IMAPClientFactory */
private $imapClientFactory;
- /** var LoggerInterface */
+ /** @var LoggerInterface */
private $logger;
+ /** @var TagMapper */
+ private $tagMapper;
+
public function __construct(AutoConfig $autoConfig,
AccountService $accountService,
ICrypto $crypto,
SmtpClientFactory $smtpClientFactory,
IMAPClientFactory $imapClientFactory,
- LoggerInterface $logger) {
+ LoggerInterface $logger,
+ TagMapper $tagMapper) {
$this->autoConfig = $autoConfig;
$this->accountService = $accountService;
$this->crypto = $crypto;
$this->smtpClientFactory = $smtpClientFactory;
$this->imapClientFactory = $imapClientFactory;
$this->logger = $logger;
+ $this->tagMapper = $tagMapper;
}
/**
@@ -78,6 +84,8 @@ class SetupService {
* @param string $emailAddress
* @param string $password
* @return Account|null
+ *
+ * @link https://github.com/nextcloud/mail/issues/25
*/
public function createNewAutoConfiguredAccount($accountName, $emailAddress, $password) {
$this->logger->info('setting up auto detected account');
@@ -88,6 +96,8 @@ class SetupService {
$this->accountService->save($mailAccount);
+ $this->tagMapper->createDefaultTags($mailAccount);
+
return new Account($mailAccount);
}
@@ -139,6 +149,8 @@ class SetupService {
$this->accountService->save($newAccount);
$this->logger->debug("account created " . $newAccount->getId());
+ $this->tagMapper->createDefaultTags($newAccount);
+
return $account;
}
diff --git a/lib/Service/Sync/ImapToDbSynchronizer.php b/lib/Service/Sync/ImapToDbSynchronizer.php
index 3132aad06..2adba1ee2 100644
--- a/lib/Service/Sync/ImapToDbSynchronizer.php
+++ b/lib/Service/Sync/ImapToDbSynchronizer.php
@@ -292,8 +292,8 @@ class ImapToDbSynchronizer {
}
foreach (array_chunk($imapMessages['messages'], 500) as $chunk) {
- $this->dbMapper->insertBulk(...array_map(function (IMAPMessage $imapMessage) use ($mailbox) {
- return $imapMessage->toDbMessage($mailbox->getId());
+ $this->dbMapper->insertBulk($account, ...array_map(function (IMAPMessage $imapMessage) use ($mailbox, $account) {
+ return $imapMessage->toDbMessage($mailbox->getId(), $account->getMailAccount());
}, $chunk));
}
$perf->step('persist messages in database');
@@ -349,8 +349,8 @@ class ImapToDbSynchronizer {
$perf->step('get new messages via Horde');
foreach (array_chunk($response->getNewMessages(), 500) as $chunk) {
- $dbMessages = array_map(function (IMAPMessage $imapMessage) use ($mailbox) {
- return $imapMessage->toDbMessage($mailbox->getId());
+ $dbMessages = array_map(function (IMAPMessage $imapMessage) use ($mailbox, $account) {
+ return $imapMessage->toDbMessage($mailbox->getId(), $account->getMailAccount());
}, $chunk);
$this->dispatcher->dispatch(
@@ -359,7 +359,7 @@ class ImapToDbSynchronizer {
);
$perf->step('classified a chunk of new messages');
- $this->dbMapper->insertBulk(...$dbMessages);
+ $this->dbMapper->insertBulk($account, ...$dbMessages);
}
$perf->step('persist new messages');
@@ -378,8 +378,8 @@ class ImapToDbSynchronizer {
$perf->step('get changed messages via Horde');
foreach (array_chunk($response->getChangedMessages(), 500) as $chunk) {
- $this->dbMapper->updateBulk(...array_map(function (IMAPMessage $imapMessage) use ($mailbox) {
- return $imapMessage->toDbMessage($mailbox->getId());
+ $this->dbMapper->updateBulk($account, ...array_map(function (IMAPMessage $imapMessage) use ($mailbox, $account) {
+ return $imapMessage->toDbMessage($mailbox->getId(), $account->getMailAccount());
}, $chunk));
}
$perf->step('persist changed messages');