John Alberts
7 years ago
9 changed files with 189 additions and 0 deletions
@ -0,0 +1,167 @@ |
|||
<?php namespace App\SupportedApps; |
|||
|
|||
use GuzzleHttp\Exception\GuzzleException; |
|||
use GuzzleHttp\Client; |
|||
use Illuminate\Support\Facades\Log; |
|||
|
|||
class Transmission implements Contracts\Applications, Contracts\Livestats |
|||
{ |
|||
|
|||
private $_client; |
|||
private $_clientOptions = array(); |
|||
|
|||
public function __construct() |
|||
{ |
|||
$body = array(); |
|||
$body["method"] = "torrent-get"; |
|||
$body["arguments"] = array("fields" => ["percentDone","status","rateDownload","rateUpload"]); |
|||
$this->_client = new Client( |
|||
['http_errors' => false, |
|||
'timeout' => 10, |
|||
'body' => json_encode($body)] |
|||
); |
|||
} |
|||
|
|||
public function defaultColour() |
|||
{ |
|||
return '#950003'; |
|||
} |
|||
public function icon() |
|||
{ |
|||
return 'supportedapps/Transmission.png'; |
|||
} |
|||
public function configDetails() |
|||
{ |
|||
return 'transmission'; |
|||
} |
|||
public function testConfig() |
|||
{ |
|||
$res = $this->sendRequest(); |
|||
if ($res == null) { |
|||
echo 'Transmission connection failed'; |
|||
return; |
|||
} |
|||
switch($res->getStatusCode()) { |
|||
case 200: |
|||
$data = json_decode($res->getBody()); |
|||
echo "Successfully connected with status: ".$data->result."\n"; |
|||
break; |
|||
case 401: |
|||
echo 'Failed: Invalid credentials'; |
|||
break; |
|||
case 404: |
|||
echo 'Failed: Please make sure your URL is correct and includes the port'; |
|||
break; |
|||
case 409: |
|||
echo 'Failed: Incorrect session id'; |
|||
break; |
|||
default: |
|||
echo 'Something went wrong... Code: '.$res->getStatusCode(); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
public function executeConfig() |
|||
{ |
|||
$html = ''; |
|||
$active = 'active'; |
|||
$res = $this->sendRequest(); |
|||
if ($res == null) { |
|||
Log::debug('Transmission connection failed'); |
|||
return ''; |
|||
} |
|||
$data = json_decode($res->getBody()); |
|||
if (! isset($data->arguments)) { |
|||
Log::debug('Failed to fetch data from Transmission'); |
|||
return ''; |
|||
} |
|||
$torrents = $data->arguments->torrents; |
|||
$torrentCount = count($torrents); |
|||
$rateDownload = $rateUpload = $completedTorrents = 0; |
|||
foreach ($torrents as $thisTorrent) { |
|||
$rateDownload += $thisTorrent->rateDownload; |
|||
$rateUpload += $thisTorrent->rateUpload; |
|||
if ($thisTorrent->percentDone == 1) { |
|||
$completedTorrents += 1; |
|||
} |
|||
} |
|||
if ($torrentCount - $completedTorrents == 0) { |
|||
// Don't poll as frequently if we don't have any active torrents |
|||
$active = 'inactive'; |
|||
} |
|||
|
|||
$html = ' |
|||
<ul class="livestats"> |
|||
<li><span class="title">Done</span><sub>'.$completedTorrents.' / '.$torrentCount.'</sub></li> |
|||
<li><span class="title">Down</span><sub>'.format_bytes($rateDownload).'</sub></li> |
|||
<li><span class="title">Up</span><sub>'.format_bytes($rateUpload).'</sub></li> |
|||
</ul> |
|||
'; |
|||
return json_encode(['status' => $active, 'html' => $html]);; |
|||
} |
|||
|
|||
private function sendRequest() |
|||
{ |
|||
$optionsSet = $this->setClientOptions(); |
|||
if (! $optionsSet) { |
|||
// Pass the failed response back up the chain |
|||
return null; |
|||
} |
|||
$res = $this->torrentGet(); |
|||
if ($res->getStatusCode() == 409) { |
|||
$this->setClientOptions(); |
|||
$res = $this->torrentGet(); |
|||
} |
|||
return $res; |
|||
} |
|||
|
|||
private function torrentGet() |
|||
{ |
|||
$res = null; |
|||
try{ |
|||
$res = $this->_client->request( |
|||
'POST', |
|||
$this->getApiUrl(), |
|||
$this->_clientOptions |
|||
); |
|||
}catch(\GuzzleHttp\Exception\BadResponseException $e){ |
|||
Log::error("Connection to {$e->getRequest()->getUrl()} failed"); |
|||
Log::debug($e->getMessage()); |
|||
$res = $e->getRequest(); |
|||
}catch(\GuzzleHttp\Exception\ConnectException $e) { |
|||
Log::error("Transmission connection refused"); |
|||
Log::debug($e->getMessage()); |
|||
} |
|||
|
|||
return $res; |
|||
} |
|||
|
|||
private function setClientOptions() |
|||
{ |
|||
if ($this->config->username != '' || $this->config->password != '') { |
|||
$this->_clientOptions = ['auth'=> [$this->config->username, $this->config->password, 'Basic']]; |
|||
} |
|||
try{ |
|||
$res = $this->_client->request('HEAD', $this->getApiUrl(), $this->_clientOptions); |
|||
$xtId = $res->getHeaderLine('X-Transmission-Session-Id'); |
|||
if ($xtId != null) { |
|||
$this->_clientOptions['headers'] = ['X-Transmission-Session-Id' => $xtId]; |
|||
} else { |
|||
Log::error("Unable to get Transmission session information"); |
|||
Log::debug("Status Code: ".$res->getStatusCode()); |
|||
} |
|||
}catch(\GuzzleHttp\Exception\ConnectException $e){ |
|||
Log::error("Failed connection to Transmission"); |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
private function getApiUrl() |
|||
{ |
|||
$url = $this->config->url; |
|||
$url = rtrim($url, '/'); |
|||
$apiUrl = $url.'/transmission/rpc'; |
|||
return $apiUrl; |
|||
} |
|||
} |
@ -0,0 +1,16 @@ |
|||
<h2>{{ __('app.apps.config') }} ({{ __('app.optional') }})</h2> |
|||
<div class="items"> |
|||
<input type="hidden" name="config[enabled]" value="1" /> |
|||
<input type="hidden" data-config="type" class="config-item" name="config[type]" value="\App\SupportedApps\Transmission" /> |
|||
<div class="input"> |
|||
<label>{{ __('app.apps.username') }}</label> |
|||
{!! Form::text('config[username]', null, array('placeholder' => __('app.apps.username'), 'data-config' => 'username', 'class' => 'form-control config-item')) !!} |
|||
</div> |
|||
<div class="input"> |
|||
<label>{{ __('app.apps.password') }}</label> |
|||
{!! Form::text('config[password]', null, array('placeholder' => __('app.apps.password'), 'data-config' => 'password', 'class' => 'form-control config-item')) !!} |
|||
</div> |
|||
<div class="input"> |
|||
<button style="margin-top: 32px;" class="btn test" id="test_config">Test</button> |
|||
</div> |
|||
</div> |
@ -0,0 +1 @@ |
|||
/config/www/backgrounds |
@ -0,0 +1 @@ |
|||
/config/www/icons |
After Width: | Height: | Size: 38 KiB |
Loading…
Reference in new issue