Merge pull request #3337 from nextcloud/enhancement/in-reply-to-references-thread-id

Store the `references`, `in-reply-to` and the thread root id
This commit is contained in:
Christoph Wurst 2020-07-06 10:24:48 +02:00 коммит произвёл GitHub
Родитель b0bdb6fa17 dc2cd0cea5
Коммит 6bf5354d68
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 108 добавлений и 2 удалений

Просмотреть файл

@ -12,7 +12,7 @@
- **🙈 Were not reinventing the wheel!** Based on the great [Horde](http://horde.org) libraries. - **🙈 Were not reinventing the wheel!** Based on the great [Horde](http://horde.org) libraries.
- **📬 Want to host your own mail server?** We dont have to reimplement this as you could set up [Mail-in-a-Box](https://mailinabox.email)! - **📬 Want to host your own mail server?** We dont have to reimplement this as you could set up [Mail-in-a-Box](https://mailinabox.email)!
]]></description> ]]></description>
<version>1.5.0-alpha1</version> <version>1.5.0-alpha2</version>
<licence>agpl</licence> <licence>agpl</licence>
<author>Christoph Wurst</author> <author>Christoph Wurst</author>
<author>Roeland Jago Douma</author> <author>Roeland Jago Douma</author>

Просмотреть файл

@ -25,16 +25,20 @@ declare(strict_types=1);
namespace OCA\Mail\Db; namespace OCA\Mail\Db;
use Horde_Mail_Rfc822_Identification;
use JsonSerializable; use JsonSerializable;
use OCA\Mail\AddressList; use OCA\Mail\AddressList;
use OCP\AppFramework\Db\Entity; use OCP\AppFramework\Db\Entity;
use function in_array; use function in_array;
use function json_encode;
/** /**
* @method void setUid(int $uid) * @method void setUid(int $uid)
* @method int getUid() * @method int getUid()
* @method void setMessageId(string $id)
* @method string getMessageId() * @method string getMessageId()
* @method string|null getReferences()
* @method string|null getInReplyTo()
* @method string|null getThreadRootId()
* @method void setMailboxId(int $mailbox) * @method void setMailboxId(int $mailbox)
* @method int getMailboxId() * @method int getMailboxId()
* @method void setSubject(string $subject) * @method void setSubject(string $subject)
@ -83,6 +87,9 @@ class Message extends Entity implements JsonSerializable {
protected $uid; protected $uid;
protected $messageId; protected $messageId;
protected $references;
protected $inReplyTo;
protected $threadRootId;
protected $mailboxId; protected $mailboxId;
protected $subject; protected $subject;
protected $sentAt; protected $sentAt;
@ -134,6 +141,28 @@ class Message extends Entity implements JsonSerializable {
$this->addType('updatedAt', 'integer'); $this->addType('updatedAt', 'integer');
} }
public function setMessageId(?string $messageId): void {
$this->setMessageIdFieldIfNotEmpty('messageId', $messageId);
}
public function setReferences(?string $references): void {
$parsed = new Horde_Mail_Rfc822_Identification($references);
$this->setter('references', [json_encode($parsed->ids)]);
}
public function setInReplyTo(?string $inReplyTo): void {
$this->setMessageIdFieldIfNotEmpty('inReplyTo', $inReplyTo);
}
public function setThreadRootId(?string $messageId): void {
$this->setMessageIdFieldIfNotEmpty('threadRootId', $messageId);
}
private function setMessageIdFieldIfNotEmpty(string $field, ?string $id): void {
$parsed = new Horde_Mail_Rfc822_Identification($id);
$this->setter($field, [$parsed->ids[0] ?? null]);
}
/** /**
* @return AddressList * @return AddressList
*/ */

Просмотреть файл

@ -93,6 +93,9 @@ class MessageMapper extends QBMapper {
$qb1->insert($this->getTableName()); $qb1->insert($this->getTableName());
$qb1->setValue('uid', $qb1->createParameter('uid')); $qb1->setValue('uid', $qb1->createParameter('uid'));
$qb1->setValue('message_id', $qb1->createParameter('message_id')); $qb1->setValue('message_id', $qb1->createParameter('message_id'));
$qb1->setValue('references', $qb1->createParameter('references'));
$qb1->setValue('in_reply_to', $qb1->createParameter('in_reply_to'));
$qb1->setValue('thread_root_id', $qb1->createParameter('thread_root_id'));
$qb1->setValue('mailbox_id', $qb1->createParameter('mailbox_id')); $qb1->setValue('mailbox_id', $qb1->createParameter('mailbox_id'));
$qb1->setValue('subject', $qb1->createParameter('subject')); $qb1->setValue('subject', $qb1->createParameter('subject'));
$qb1->setValue('sent_at', $qb1->createParameter('sent_at')); $qb1->setValue('sent_at', $qb1->createParameter('sent_at'));
@ -116,6 +119,12 @@ class MessageMapper extends QBMapper {
foreach ($messages as $message) { foreach ($messages as $message) {
$qb1->setParameter('uid', $message->getUid(), IQueryBuilder::PARAM_INT); $qb1->setParameter('uid', $message->getUid(), IQueryBuilder::PARAM_INT);
$qb1->setParameter('message_id', $message->getMessageId(), IQueryBuilder::PARAM_STR); $qb1->setParameter('message_id', $message->getMessageId(), IQueryBuilder::PARAM_STR);
$inReplyTo = $message->getInReplyTo();
$qb1->setParameter('in_reply_to', $inReplyTo, $inReplyTo === null ? IQueryBuilder::PARAM_NULL : IQueryBuilder::PARAM_STR);
$references = $message->getReferences();
$qb1->setParameter('references', $references, $references === null ? IQueryBuilder::PARAM_NULL : IQueryBuilder::PARAM_STR);
$threadRootId = $message->getThreadRootId();
$qb1->setParameter('thread_root_id', $threadRootId,$threadRootId === null ? IQueryBuilder::PARAM_NULL : IQueryBuilder::PARAM_STR);
$qb1->setParameter('mailbox_id', $message->getMailboxId(), IQueryBuilder::PARAM_INT); $qb1->setParameter('mailbox_id', $message->getMailboxId(), IQueryBuilder::PARAM_INT);
$qb1->setParameter('subject', $message->getSubject(), IQueryBuilder::PARAM_STR); $qb1->setParameter('subject', $message->getSubject(), IQueryBuilder::PARAM_STR);
$qb1->setParameter('sent_at', $message->getSentAt(), IQueryBuilder::PARAM_INT); $qb1->setParameter('sent_at', $message->getSentAt(), IQueryBuilder::PARAM_INT);

Просмотреть файл

@ -200,6 +200,16 @@ class MessageMapper {
$query->flags(); $query->flags();
$query->uid(); $query->uid();
$query->imapDate(); $query->imapDate();
$query->headers(
'references',
[
'references',
],
[
'cache' => true,
'peek' => true,
]
);
$fetchResults = iterator_to_array($client->fetch($mailbox, $query, [ $fetchResults = iterator_to_array($client->fetch($mailbox, $query, [
'ids' => new Horde_Imap_Client_Ids($ids), 'ids' => new Horde_Imap_Client_Ids($ids),

Просмотреть файл

@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace OCA\Mail\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\SimpleMigrationStep;
use OCP\Migration\IOutput;
class Version1050Date20200624101359 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return ISchemaWrapper
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$messagesTable = $schema->getTable('mail_messages');
$messagesTable->getColumn('message_id')->setLength(1023);
$messagesTable->addColumn('references', 'text', [
'notnull' => false,
]);
$messagesTable->addColumn('in_reply_to', 'string', [
'notnull' => false,
'length' => 1023,
]);
$messagesTable->addColumn('thread_root_id', 'string', [
'notnull' => false,
'length' => 1023,
]);
return $schema;
}
}

Просмотреть файл

@ -38,6 +38,7 @@ use Horde_Imap_Client_Fetch_Query;
use Horde_Imap_Client_Ids; use Horde_Imap_Client_Ids;
use Horde_Imap_Client_Mailbox; use Horde_Imap_Client_Mailbox;
use Horde_Imap_Client_Socket; use Horde_Imap_Client_Socket;
use Horde_Mime_Headers;
use Horde_Mime_Part; use Horde_Mime_Part;
use JsonSerializable; use JsonSerializable;
use OC; use OC;
@ -163,6 +164,20 @@ class IMAPMessage implements IMessage, JsonSerializable {
return $this->fetch->getEnvelope(); return $this->fetch->getEnvelope();
} }
private function getRawReferences(): string {
/** @var Horde_Mime_Headers $headers */
$headers = $this->fetch->getHeaders('references', Horde_Imap_Client_Data_Fetch::HEADER_PARSE);
$header = $headers->getHeader('references');
if ($header === null) {
return '';
}
return $header->value_single;
}
private function getRawInReplyTo(): string {
return $this->fetch->getEnvelope()->in_reply_to;
}
/** /**
* @return AddressList * @return AddressList
*/ */
@ -630,6 +645,9 @@ class IMAPMessage implements IMessage, JsonSerializable {
$msg->setUid($this->getUid()); $msg->setUid($this->getUid());
$msg->setMessageId($this->getMessageId()); $msg->setMessageId($this->getMessageId());
$msg->setReferences($this->getRawReferences());
$msg->setThreadRootId($this->getMessageId());
$msg->setInReplyTo($this->getRawInReplyTo());
$msg->setMailboxId($mailboxId); $msg->setMailboxId($mailboxId);
$msg->setFrom($this->getFrom()); $msg->setFrom($this->getFrom());
$msg->setTo($this->getTo()); $msg->setTo($this->getTo());