diff --git a/src/DuplicateTorrentException.php b/src/DuplicateTorrentException.php index 7bcf931..05947ee 100644 --- a/src/DuplicateTorrentException.php +++ b/src/DuplicateTorrentException.php @@ -4,5 +4,66 @@ class DuplicateTorrentException extends \Exception { + /** + * @var int + */ + private $torrentId; + /** + * @var string + */ + private $torrentName; + + /** + * @var string + */ + private $torrentHashString; + + /** + * @return int + */ + public function getTorrentId() + { + return $this->torrentId; + } + + /** + * @param int $torrentId + */ + public function setTorrentId($torrentId) + { + $this->torrentId = $torrentId; + } + + /** + * @return string + */ + public function getTorrentName() + { + return $this->torrentName; + } + + /** + * @param string $torrentName + */ + public function setTorrentName($torrentName) + { + $this->torrentName = $torrentName; + } + + /** + * @return string + */ + public function getTorrentHashString() + { + return $this->torrentHashString; + } + + /** + * @param string $torrentHashString + */ + public function setTorrentHashString($torrentHashString) + { + $this->torrentHashString = $torrentHashString; + } } diff --git a/src/RpcClient.php b/src/RpcClient.php index 4fde7f2..2870fb4 100644 --- a/src/RpcClient.php +++ b/src/RpcClient.php @@ -215,10 +215,24 @@ public function torrentAdd($sessionId, array $argumentsWithValues) )); } - $response = $this->sendRequest($sessionId, $this->buildRequestBody( - 'torrent-add', - $argumentsWithValues - )); + try { + $response = $this->sendRequest($sessionId, $this->buildRequestBody( + 'torrent-add', + $argumentsWithValues + )); + } catch (TransmissionException $e) { + if ($e->getResult() === 'duplicate torrent') { + $responseArguments = $e->getArguments(); + $duplicateTorrentException = new DuplicateTorrentException(); + $duplicateTorrentException->setTorrentId($responseArguments['torrent-duplicate']['id']); + $duplicateTorrentException->setTorrentName($responseArguments['torrent-duplicate']['name']); + $duplicateTorrentException->setTorrentHashString($responseArguments['torrent-duplicate']['hashString']); + + throw $duplicateTorrentException; + } + + throw $e; + } return $response['arguments']['torrent-added']; } @@ -569,6 +583,7 @@ private function sendRequest($sessionId, $requestBody) if ($responseBody['result'] !== 'success') { $e = new TransmissionException('The Transmission RPC API returned an error: ' . $responseBody['result']); $e->setResult($responseBody['result']); + $e->setArguments($responseBody['arguments']); if (!is_null($this->logger)) { $this->logger->error( diff --git a/src/TransmissionException.php b/src/TransmissionException.php index 80f2493..31f6a62 100644 --- a/src/TransmissionException.php +++ b/src/TransmissionException.php @@ -9,6 +9,11 @@ class TransmissionException extends \Exception */ private $result; + /** + * @var array + */ + private $arguments; + /** * @return string */ @@ -24,4 +29,20 @@ public function setResult($result) { $this->result = $result; } + + /** + * @return array + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * @param array $arguments + */ + public function setArguments(array $arguments) + { + $this->arguments = $arguments; + } } diff --git a/tests/RpcClientTest.php b/tests/RpcClientTest.php index 000a919..b829708 100644 --- a/tests/RpcClientTest.php +++ b/tests/RpcClientTest.php @@ -4,6 +4,7 @@ use GuzzleHttp\Exception\ClientException; use Martial\Transmission\API\CSRFException; +use Martial\Transmission\API\DuplicateTorrentException; use Martial\Transmission\API\RpcClient; use Martial\Transmission\API\TransmissionException; use Mockery as m; @@ -701,6 +702,40 @@ public function testTorrentAddShouldThrowAnExceptionWithAnInvalidSessionId() } } + public function testTorrentAddShouldThrowAnExceptionWithDuplicateTorrent() + { + $success = false; + $arguments = ['filename' => '/path/to/Fedora.torrent']; + $requestBody = '{"method":"torrent-add","arguments":{"filename":"/path/to/Fedora.torrent"}}'; + $hashString = md5('Fedora.iso'); + $torrentId = 42; + $torrentName = 'Fedora.iso'; + + $this + ->sendRequest($requestBody) + ->andReturn($this->guzzleResponse); + + $this->setResponseBody(sprintf( + '{"arguments":{"torrent-duplicate":{"id":%d,"name":"%s","hashString":"%s"}},"result":"duplicate torrent"}', + $torrentId, + $torrentName, + $hashString + )); + + try { + $this->rpcClient->torrentAdd($this->sessionId, $arguments); + } catch (DuplicateTorrentException $e) { + $this->assertSame($torrentId, $e->getTorrentId()); + $this->assertSame($torrentName, $e->getTorrentName()); + $this->assertSame($hashString, $e->getTorrentHashString()); + $success = true; + } + + if (!$success) { + $this->fail('DuplicateTorrentException was not thrown.'); + } + } + public function testTorrentRemoveWithLocalDataWithSuccess() { $requestBody = '{"method":"torrent-remove","arguments":{"ids":[42,1337],"delete-local-data":true}}';