Skip to content

Commit

Permalink
Add request-response based synchronizer around horde sync
Browse files Browse the repository at this point in the history
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
  • Loading branch information
ChristophWurst committed Feb 28, 2017
1 parent b98fe0e commit ee414f4
Show file tree
Hide file tree
Showing 9 changed files with 456 additions and 4 deletions.
14 changes: 14 additions & 0 deletions lib/Contracts/IMailManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,22 @@
namespace OCA\Mail\Contracts;

use OCA\Mail\Account;
use OCA\Mail\Folder;
use OCA\Mail\IMAP\Sync\Request as SyncRequest;
use OCA\Mail\IMAP\Sync\Response as SyncResponse;

interface IMailManager {

/**
* @param Account $account
* @return Folder[]
*/
public function getFolders(Account $account);

/**
* @param Account
* @param SyncRequest $syncRequest
* @return SyncResponse
*/
public function syncMessages(Account $account, SyncRequest $syncRequest);
}
41 changes: 41 additions & 0 deletions lib/IMAP/MessageMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

/**
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
*
* Mail
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/

namespace OCA\Mail\IMAP;

use Exception;
use Horde_Imap_Client_Base;
use OCA\Mail\Folder;
use OCA\Mail\Model\IMAPMessage;

class MessageMapper {

/**
* @param Horde_Imap_Client_Base $imapClient
* @param Folder $mailbox
* @param array $ids
* @return IMAPMessage[]
*/
public function findByIds(Horde_Imap_Client_Base $imapClient, $mailbox, array $ids) {
throw new Exception('not implemented');
}

}
57 changes: 57 additions & 0 deletions lib/IMAP/Sync/Request.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

/**
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
*
* Mail
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/

namespace OCA\Mail\IMAP\Sync;

class Request {

/** @var string */
private $mailbox;

/** @var string */
private $syncToken;

/**
* @param string $mailbox
* @param string $syncToken
*/
public function __construct($mailbox, $syncToken) {
$this->mailbox = $mailbox;
$this->syncToken = $syncToken;
}

/**
* Get the mailbox name
*
* @return string
*/
public function getMailbox() {
return $this->mailbox;
}

/**
* @return string the Horde sync token
*/
public function getToken() {
return $this->syncToken;
}

}
68 changes: 68 additions & 0 deletions lib/IMAP/Sync/Response.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

/**
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
*
* Mail
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/

namespace OCA\Mail\IMAP\Sync;

use Exception;
use JsonSerializable;
use OCA\Mail\Model\IMAPMessage;

class Response implements JsonSerializable {

/** @var string */
private $syncToken;

/** @var IMAPMessage[] */
private $newMessages;

/** @var IMAPMessage[] */
private $changedMessages;

/** @var array */
private $vanishedMessages;

/**
* @param string $syncToken
* @param IMAPMessage[] $newMessages
* @param IMAPMessage[] $changedMessages
* @param array $vanishedMessages
*/
public function __construct($syncToken, array $newMessages = [], array $changedMessages = [],
array $vanishedMessages = []) {
$this->syncToken = $syncToken;
$this->newMessages = $newMessages;
$this->changedMessages = $changedMessages;
$this->vanishedMessages = $vanishedMessages;
}

/**
* @return array
*/
public function jsonSerialize() {
return [
'newMessages' => $this->newMessages,
'changedMessages' => $this->changedMessages,
'vanishedMessages' => $this->vanishedMessages,
'token' => $this->syncToken,
];
}

}
57 changes: 57 additions & 0 deletions lib/IMAP/Sync/Synchronizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

/**
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
*
* Mail
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/

namespace OCA\Mail\IMAP\Sync;

use Horde_Imap_Client_Base;
use OCA\Mail\IMAP\MessageMapper;
use OCA\Mail\IMAP\Sync\Request;
use OCA\Mail\IMAP\Sync\Response;

class Synchronizer {

/** @var MessageMapper */
private $messageMapper;

/**
* @param MessageMapper $messageMapper
*/
public function __construct(MessageMapper $messageMapper) {
$this->messageMapper = $messageMapper;
}

/**
* @param Horde_Imap_Client_Base $imapClient
* @param Request $request
* @return Response
*/
public function sync(Horde_Imap_Client_Base $imapClient, Request $request) {
$hordeSync = $imapClient->sync($request->getMailbox(), $request->getToken());

$newMessages = $this->messageMapper->findByIds($imapClient, $request->getMailbox(), $hordeSync->newmsgsuids->ids);
$changedMessages = $this->messageMapper->findByIds($imapClient, $request->getMailbox(), $hordeSync->flagsuids->ids);
$vanishedMessages = $hordeSync->vanisheduids->ids;

$newSyncToken = $imapClient->getSyncToken($request->getMailbox());
return new Response($newSyncToken, $newMessages, $changedMessages, $vanishedMessages);
}

}
30 changes: 26 additions & 4 deletions lib/Service/MailManager.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php


/**
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
*
Expand All @@ -24,7 +25,12 @@
use OCA\Mail\Account;
use OCA\Mail\Contracts\IMailManager;
use OCA\Mail\Folder;
use OCA\Mail\Service\IMAP\IMAPClientFactory;
use OCA\Mail\IMAP\IMAPClientFactory;
use OCA\Mail\IMAP\Sync\Request;
use OCA\Mail\IMAP\Sync\Response;
use OCA\Mail\IMAP\Sync\Synchronizer;
use OCA\Mail\Service\FolderMapper;
use OCA\Mail\Service\FolderNameTranslator;

class MailManager implements IMailManager {

Expand All @@ -37,16 +43,21 @@ class MailManager implements IMailManager {
/** @var FolderNameTranslator */
private $folderNameTranslator;

/** @var Synchronizer */
private $synchronizer;

/**
* @param IMAPClientFactory $imapClientFactory
* @param FolderMapper $folderMapper
* @param FolderNameTranslator
* @param FolderNameTranslator $folderNameTranslator
* @param Synchronizer $synchronizer
*/
public function __construct(IMAPClientFactory $imapClientFactory,
FolderMapper $folderMapper, FolderNameTranslator $folderNameTranslator) {
public function __construct(IMAPClientFactory $imapClientFactory, FolderMapper $folderMapper,
FolderNameTranslator $folderNameTranslator, Synchronizer $synchronizer) {
$this->imapClientFactory = $imapClientFactory;
$this->folderMapper = $folderMapper;
$this->folderNameTranslator = $folderNameTranslator;
$this->synchronizer = $synchronizer;
}

/**
Expand All @@ -64,4 +75,15 @@ public function getFolders(Account $account) {
return $this->folderMapper->buildFolderHierarchy($folders);
}

/**
* @param Account $account
* @param Request $syncRequest
* @return Response
*/
public function syncMessages(Account $account, Request $syncRequest) {
$client = $this->imapClientFactory->getClient($account);

return $this->synchronizer->sync($client, $syncRequest);
}

}
55 changes: 55 additions & 0 deletions tests/IMAP/Sync/RequestTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

/**
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
*
* Mail
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/

namespace OCA\Mail\Tests\IMAP\Sync;

use OCA\Mail\IMAP\Sync\Request;
use PHPUnit_Framework_TestCase;

class RequestTest extends PHPUnit_Framework_TestCase {

/** @var string */
private $mailbox;

/** @var string */
private $syncToken;

/** @var Request */
private $request;

protected function setUp() {
parent::setUp();

$this->mailbox = 'inbox';
$this->syncToken = 'ab123';

$this->request = new Request($this->mailbox, $this->syncToken);
}

public function testGetMailbox() {
$this->assertEquals($this->mailbox, $this->request->getMailbox());
}

public function testGetSyncToken() {
$this->assertEquals($this->syncToken, $this->request->getToken());
}

}
Loading

0 comments on commit ee414f4

Please sign in to comment.