Skip to content

Commit 9b9586f

Browse files
feat: jmap support - part 2
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
1 parent b7dd12e commit 9b9586f

70 files changed

Lines changed: 4423 additions & 1983 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

appinfo/info.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ Learn more about the Nextcloud Ethical AI Rating [in our blog](https://nextcloud
9191
<command>OCA\Mail\Command\SyncAccount</command>
9292
<command>OCA\Mail\Command\Thread</command>
9393
<command>OCA\Mail\Command\TrainAccount</command>
94-
<command>OCA\Mail\Command\UpdateAccount</command>
94+
<command>OCA\Mail\Command\UpdateImapAccount</command>
95+
<command>OCA\Mail\Command\UpdateJmapAccount</command>
9596
<command>OCA\Mail\Command\UpdateSystemAutoresponders</command>
9697
<command>OCA\Mail\Command\RunMetaEstimator</command>
9798
</commands>

appinfo/routes.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@
226226
'verb' => 'GET'
227227
],
228228
[
229-
'name' => 'messages#getSource',
229+
'name' => 'messages#getRawMessage',
230230
'url' => '/api/messages/{id}/source',
231231
'verb' => 'GET'
232232
],

lib/AppInfo/Application.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
use OCA\Mail\Contracts\IAvatarService;
1717
use OCA\Mail\Contracts\IDkimService;
1818
use OCA\Mail\Contracts\IDkimValidator;
19-
use OCA\Mail\Contracts\IMailManager;
2019
use OCA\Mail\Contracts\IMailSearch;
2120
use OCA\Mail\Contracts\IMailTransmission;
2221
use OCA\Mail\Contracts\ITrustedSenderService;
@@ -62,7 +61,6 @@
6261
use OCA\Mail\Service\AvatarService;
6362
use OCA\Mail\Service\DkimService;
6463
use OCA\Mail\Service\DkimValidator;
65-
use OCA\Mail\Service\MailManager;
6664
use OCA\Mail\Service\MailTransmission;
6765
use OCA\Mail\Service\Search\MailSearch;
6866
use OCA\Mail\Service\TrustedSenderService;
@@ -120,7 +118,6 @@ public function register(IRegistrationContext $context): void {
120118

121119
$context->registerServiceAlias(IAvatarService::class, AvatarService::class);
122120
$context->registerServiceAlias(IAttachmentService::class, AttachmentService::class);
123-
$context->registerServiceAlias(IMailManager::class, MailManager::class);
124121
$context->registerServiceAlias(IMailSearch::class, MailSearch::class);
125122
$context->registerServiceAlias(IMailTransmission::class, MailTransmission::class);
126123
$context->registerServiceAlias(ITrustedSenderService::class, TrustedSenderService::class);

lib/BackgroundJob/ContextChat/SubmitContentJob.php

Lines changed: 30 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
use OCA\Mail\Db\MessageMapper;
1616
use OCA\Mail\Exception\ServiceException;
1717
use OCA\Mail\Exception\SmimeDecryptException;
18-
use OCA\Mail\IMAP\IMAPClientFactory;
1918
use OCA\Mail\Service\AccountService;
2019
use OCA\Mail\Service\ContextChat\TaskService;
2120
use OCA\Mail\Service\MailManager;
@@ -36,7 +35,6 @@ public function __construct(
3635
private AccountService $accountService,
3736
private MailManager $mailManager,
3837
private MessageMapper $messageMapper,
39-
private IMAPClientFactory $clientFactory,
4038
private ContextChatProvider $contextChatProvider,
4139
private IContentManager $contentManager,
4240
private LoggerInterface $logger,
@@ -109,53 +107,41 @@ protected function run($argument): void {
109107
}
110108

111109

112-
$client = $this->clientFactory->getClient($account);
113110
$items = [];
114111

115-
try {
116-
$startTime = $this->time->getTime();
117-
foreach ($messages as $message) {
118-
if ($this->time->getTime() - $startTime > ContextChatProvider::CONTEXT_CHAT_JOB_INTERVAL) {
119-
break;
120-
}
121-
try {
122-
$imapMessage = $this->mailManager->getImapMessage($client, $account, $mailbox, $message->getUid(), true);
123-
} catch (ServiceException $e) {
124-
// couldn't load message, let's skip it. Retrying would be too costly
125-
continue;
126-
} catch (SmimeDecryptException $e) {
127-
// encryption problem, skip this message
128-
continue;
129-
}
130-
131-
132-
// Skip encrypted messages
133-
if ($imapMessage->isEncrypted()) {
134-
continue;
135-
}
136-
137-
138-
$fullMessage = $imapMessage->getFullMessage($imapMessage->getUid(), true);
139-
140-
141-
$items[] = new ContentItem(
142-
"{$mailbox->getId()}:{$message->getId()}",
143-
$this->contextChatProvider->getId(),
144-
$imapMessage->getSubject(),
145-
$fullMessage['body'] ?? '',
146-
'E-Mail',
147-
$imapMessage->getSentDate(),
148-
[$account->getUserId()],
149-
);
112+
$startTime = $this->time->getTime();
113+
foreach ($messages as $message) {
114+
if ($this->time->getTime() - $startTime > ContextChatProvider::CONTEXT_CHAT_JOB_INTERVAL) {
115+
break;
150116
}
151-
} catch (\Throwable $e) {
152-
$this->logger->warning('Exception occurred when trying to fetch messages for context chat', ['exception' => $e]);
153-
} finally {
154117
try {
155-
$client->close();
156-
} catch (\Horde_Imap_Client_Exception $e) {
157-
$this->logger->debug('Failed to close IMAP client', ['exception' => $e]);
118+
$imapMessage = $this->mailManager->getImapMessage($account, $mailbox, $message, true);
119+
} catch (ServiceException $e) {
120+
// couldn't load message, let's skip it. Retrying would be too costly
121+
continue;
122+
} catch (SmimeDecryptException $e) {
123+
// encryption problem, skip this message
124+
continue;
125+
}
126+
127+
128+
// Skip encrypted messages
129+
if ($imapMessage->isEncrypted()) {
130+
continue;
158131
}
132+
133+
134+
$fullMessage = $imapMessage->getFullMessage($imapMessage->getUid(), true);
135+
136+
$items[] = new ContentItem(
137+
"{$mailbox->getId()}:{$message->getId()}",
138+
$this->contextChatProvider->getId(),
139+
$imapMessage->getSubject(),
140+
$fullMessage['body'] ?? '',
141+
'E-Mail',
142+
$imapMessage->getSentDate(),
143+
[$account->getUserId()],
144+
);
159145
}
160146

161147
if (count($items) > 0) {

lib/BackgroundJob/FollowUpClassifierJob.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99

1010
namespace OCA\Mail\BackgroundJob;
1111

12-
use OCA\Mail\Contracts\IMailManager;
1312
use OCA\Mail\Db\Message;
1413
use OCA\Mail\Db\ThreadMapper;
1514
use OCA\Mail\Exception\ClientException;
1615
use OCA\Mail\Service\AccountService;
1716
use OCA\Mail\Service\AiIntegrations\AiIntegrationsService;
17+
use OCA\Mail\Service\MailManager;
1818
use OCP\AppFramework\Utility\ITimeFactory;
1919
use OCP\BackgroundJob\QueuedJob;
2020
use OCP\DB\Exception;
@@ -30,7 +30,7 @@ public function __construct(
3030
ITimeFactory $time,
3131
private LoggerInterface $logger,
3232
private AccountService $accountService,
33-
private IMailManager $mailManager,
33+
private MailManager $mailManager,
3434
private AiIntegrationsService $aiService,
3535
private ThreadMapper $threadMapper,
3636
) {
@@ -54,7 +54,7 @@ public function run($argument): void {
5454
return;
5555
}
5656

57-
$messages = $this->mailManager->getByMessageId($account, $messageId);
57+
$messages = $this->mailManager->getMessagesByMessageId($account, $messageId);
5858
$messages = array_filter(
5959
$messages,
6060
static fn (Message $message) => $message->getMailboxId() === $mailboxId,
@@ -96,12 +96,12 @@ public function run($argument): void {
9696

9797
$this->logger->debug("Message requires follow-up: {$message->getId()}");
9898
$tag = $this->mailManager->createTag('Follow up', '#d77000', $userId);
99-
$this->mailManager->tagMessage(
99+
$this->mailManager->tagMessages(
100100
$account,
101-
$mailbox->getName(),
102-
$message,
101+
$mailbox,
103102
$tag,
104103
true,
104+
$message,
105105
);
106106
}
107107
}

lib/BackgroundJob/MigrateImportantJob.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
use OCA\Mail\Db\MailboxMapper;
1515

1616
use OCA\Mail\Exception\ServiceException;
17-
use OCA\Mail\IMAP\IMAPClientFactory;
1817
use OCA\Mail\Migration\MigrateImportantFromImapAndDb;
18+
use OCA\Mail\Protocol\ProtocolFactory;
1919
use OCA\Mail\Service\MailManager;
2020
use OCP\AppFramework\Db\DoesNotExistException;
2121
use OCP\AppFramework\Utility\ITimeFactory;
@@ -28,23 +28,23 @@ class MigrateImportantJob extends QueuedJob {
2828
private MailManager $mailManager;
2929
private MigrateImportantFromImapAndDb $migration;
3030
private LoggerInterface $logger;
31-
private IMAPClientFactory $imapClientFactory;
31+
private ProtocolFactory $protocolFactory;
3232

3333
public function __construct(MailboxMapper $mailboxMapper,
3434
MailAccountMapper $mailAccountMapper,
3535
MailManager $mailManager,
3636
MigrateImportantFromImapAndDb $migration,
3737
LoggerInterface $logger,
3838
ITimeFactory $timeFactory,
39-
IMAPClientFactory $imapClientFactory,
39+
ProtocolFactory $protocolFactory,
4040
) {
4141
parent::__construct($timeFactory);
4242
$this->mailboxMapper = $mailboxMapper;
4343
$this->mailAccountMapper = $mailAccountMapper;
4444
$this->mailManager = $mailManager;
4545
$this->migration = $migration;
4646
$this->logger = $logger;
47-
$this->imapClientFactory = $imapClientFactory;
47+
$this->protocolFactory = $protocolFactory;
4848
}
4949

5050
/**
@@ -71,10 +71,10 @@ public function run($argument) {
7171
}
7272

7373
$account = new Account($mailAccount);
74-
$client = $this->imapClientFactory->getClient($account);
74+
$client = $this->protocolFactory->imapClient($account);
7575

7676
try {
77-
if ($this->mailManager->isPermflagsEnabled($client, $account, $mailbox->getName()) === false) {
77+
if ($this->mailManager->isPermflagsEnabled($account, $mailbox) === false) {
7878
$this->logger->debug("Permflags not enabled for <{$accountId}>");
7979
return;
8080
}

lib/BackgroundJob/QuotaJob.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
namespace OCA\Mail\BackgroundJob;
1010

11-
use OCA\Mail\Contracts\IMailManager;
1211
use OCA\Mail\Service\AccountService;
12+
use OCA\Mail\Service\MailManager;
1313
use OCP\AppFramework\Db\DoesNotExistException;
1414
use OCP\AppFramework\Utility\ITimeFactory;
1515
use OCP\BackgroundJob\IJobList;
@@ -22,15 +22,15 @@
2222
class QuotaJob extends TimedJob {
2323
private IUserManager $userManager;
2424
private AccountService $accountService;
25-
private IMailManager $mailManager;
25+
private MailManager $mailManager;
2626
private LoggerInterface $logger;
2727
private IJobList $jobList;
2828
private IManager $notificationManager;
2929

3030
public function __construct(ITimeFactory $time,
3131
IUserManager $userManager,
3232
AccountService $accountService,
33-
IMailManager $mailManager,
33+
MailManager $mailManager,
3434
IManager $notificationManager,
3535
LoggerInterface $logger,
3636
IJobList $jobList) {

lib/BackgroundJob/RepairSyncJob.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99

1010
namespace OCA\Mail\BackgroundJob;
1111

12+
use OCA\Mail\Db\MailAccount;
1213
use OCA\Mail\Db\MailboxMapper;
1314
use OCA\Mail\Events\SynchronizationEvent;
15+
use OCA\Mail\Protocol\ProtocolFactory;
1416
use OCA\Mail\Service\AccountService;
1517
use OCA\Mail\Service\Sync\SyncService;
1618
use OCP\AppFramework\Db\DoesNotExistException;
@@ -25,6 +27,7 @@ class RepairSyncJob extends TimedJob {
2527
public function __construct(
2628
ITimeFactory $time,
2729
private SyncService $syncService,
30+
private ProtocolFactory $protocolFactory,
2831
private AccountService $accountService,
2932
private IUserManager $userManager,
3033
private MailboxMapper $mailboxMapper,
@@ -65,6 +68,19 @@ protected function run($argument): void {
6568
return;
6669
}
6770

71+
$this->protocolFactory
72+
->mailboxConnector($account)
73+
->syncAll($account, true);
74+
75+
if ($account->getMailAccount()->getProtocol() !== MailAccount::PROTOCOL_IMAP) {
76+
$this->logger->debug(sprintf(
77+
'Account %d uses %s, skipping IMAP repair sync after mailbox refresh',
78+
$account->getId(),
79+
$account->getMailAccount()->getProtocol(),
80+
));
81+
return;
82+
}
83+
6884
$rebuildThreads = false;
6985
$trashMailboxId = $account->getMailAccount()->getTrashMailboxId();
7086
$snoozeMailboxId = $account->getMailAccount()->getSnoozeMailboxId();

lib/BackgroundJob/SyncJob.php

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010

1111
use Horde_Imap_Client_Exception;
1212
use OCA\Mail\AppInfo\Application;
13+
use OCA\Mail\Db\MailAccount;
1314
use OCA\Mail\Exception\IncompleteSyncException;
1415
use OCA\Mail\Exception\ServiceException;
15-
use OCA\Mail\IMAP\MailboxSync;
16+
use OCA\Mail\Protocol\ProtocolFactory;
1617
use OCA\Mail\Service\AccountService;
17-
use OCA\Mail\Service\Sync\ImapToDbSynchronizer;
1818
use OCP\AppFramework\Db\DoesNotExistException;
1919
use OCP\AppFramework\Utility\ITimeFactory;
2020
use OCP\BackgroundJob\IJobList;
@@ -31,8 +31,6 @@ class SyncJob extends TimedJob {
3131

3232
private IUserManager $userManager;
3333
private AccountService $accountService;
34-
private ImapToDbSynchronizer $syncService;
35-
private MailboxSync $mailboxSync;
3634
private LoggerInterface $logger;
3735
private IJobList $jobList;
3836
private readonly bool $forcedSyncInterval;
@@ -41,8 +39,7 @@ public function __construct(
4139
ITimeFactory $time,
4240
IUserManager $userManager,
4341
AccountService $accountService,
44-
MailboxSync $mailboxSync,
45-
ImapToDbSynchronizer $syncService,
42+
private ProtocolFactory $protocolFactory,
4643
LoggerInterface $logger,
4744
IJobList $jobList,
4845
private readonly IConfig $config,
@@ -51,8 +48,6 @@ public function __construct(
5148

5249
$this->userManager = $userManager;
5350
$this->accountService = $accountService;
54-
$this->syncService = $syncService;
55-
$this->mailboxSync = $mailboxSync;
5651
$this->logger = $logger;
5752
$this->jobList = $jobList;
5853

@@ -83,7 +78,8 @@ protected function run($argument) {
8378
return;
8479
}
8580

86-
if (!$account->getMailAccount()->canAuthenticateImap()) {
81+
if ($account->getMailAccount()->getProtocol() === MailAccount::PROTOCOL_IMAP
82+
&& !$account->getMailAccount()->canAuthenticateImap()) {
8783
$this->logger->debug('No authentication on IMAP possible, skipping background sync job');
8884
return;
8985
}
@@ -124,8 +120,12 @@ protected function run($argument) {
124120
}
125121

126122
try {
127-
$this->mailboxSync->sync($account, $this->logger, true);
128-
$this->syncService->syncAccount($account, $this->logger);
123+
$this->protocolFactory
124+
->mailboxConnector($account)
125+
->syncAll($account, true);
126+
$this->protocolFactory
127+
->messageConnector($account)
128+
->syncAll($account, true);
129129
} catch (IncompleteSyncException $e) {
130130
$this->logger->warning($e->getMessage(), [
131131
'exception' => $e,

0 commit comments

Comments
 (0)