This commit is contained in:
Chris 2018-03-12 09:59:43 +00:00
commit b50f4ec5ce
11 changed files with 203 additions and 2 deletions

View file

@ -31,6 +31,7 @@ class Item extends Model
'Duplicati' => \App\SupportedApps\Duplicati::class,
'Emby' => \App\SupportedApps\Emby::class,
'Gitea' => \App\SupportedApps\Gitea::class,
'Glances' => \App\SupportedApps\Glances::class,
'Graylog' => \App\SupportedApps\Graylog::class,
'Home Assistant' => \App\SupportedApps\HomeAssistant::class,
'Jackett' => \App\SupportedApps\Jackett::class,
@ -56,6 +57,7 @@ class Item extends Model
'Sabnzbd' => \App\SupportedApps\Sabnzbd::class,
'Sickrage' => \App\SupportedApps\Sickrage::class,
'Sonarr' => \App\SupportedApps\Sonarr::class,
'Transmission' => \App\SupportedApps\Transmission::class,
'Traefik' => \App\SupportedApps\Traefik::class,
'Ttrss' => \App\SupportedApps\Ttrss::class,
'UniFi' => \App\SupportedApps\Unifi::class,

View file

@ -0,0 +1,14 @@
<?php namespace App\SupportedApps;
class Glances implements Contracts\Applications {
public function defaultColour()
{
return '#2c363f';
}
public function icon()
{
return 'supportedapps/glances.png';
}
}

View file

@ -0,0 +1,166 @@
<?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;
}
}

View file

@ -14,7 +14,7 @@ return [
*/
'name' => env('APP_NAME', 'Heimdall'),
'version' => '1.4.6',
'version' => '1.4.7',
/*
|--------------------------------------------------------------------------

View file

@ -31,6 +31,7 @@ You can use the app to link to any site or application, but Foundation apps will
- NZBGet
- Pihole
- Sabnzbd
- Transmission
**Foundation**
- Deluge

View file

@ -34,7 +34,7 @@
{!! Form::text('colour', null, array('placeholder' => __('app.apps.hex'),'class' => 'form-control color-picker')) !!}
<hr />
<label>{{ __('app.apps.tags') }} ({{ __('app.optional') }})</label>
{!! Form::select('tags', $tags, $current_tags, ['class' => 'tags', 'multiple']) !!}
{!! Form::select('tags[]', $tags, $current_tags, ['class' => 'tags', 'multiple']) !!}
</div>
<div class="input">
<label>{{ __('app.apps.icon') }}</label>

View file

@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View file

@ -58,6 +58,7 @@ return array(
'App\\SupportedApps\\Sabnzbd' => $baseDir . '/app/SupportedApps/Sabnzbd.php',
'App\\SupportedApps\\Sonarr' => $baseDir . '/app/SupportedApps/Sonarr.php',
'App\\SupportedApps\\Traefik' => $baseDir . '/app/SupportedApps/Traefik.php',
'App\\SupportedApps\\Transmission' => $baseDir . '/app/SupportedApps/Transmission.php',
'App\\SupportedApps\\Ttrss' => $baseDir . '/app/SupportedApps/Ttrss.php',
'App\\SupportedApps\\Unifi' => $baseDir . '/app/SupportedApps/Unifi.php',
'App\\SupportedApps\\ruTorrent' => $baseDir . '/app/SupportedApps/ruTorrent.php',

View file

@ -396,6 +396,7 @@ class ComposerStaticInit4b6fb9210a1ea37c2db27b8ff53a1ecf
'App\\SupportedApps\\Sabnzbd' => __DIR__ . '/../..' . '/app/SupportedApps/Sabnzbd.php',
'App\\SupportedApps\\Sonarr' => __DIR__ . '/../..' . '/app/SupportedApps/Sonarr.php',
'App\\SupportedApps\\Traefik' => __DIR__ . '/../..' . '/app/SupportedApps/Traefik.php',
'App\\SupportedApps\\Transmission' => __DIR__ . '/../..' . '/app/SupportedApps/Transmission.php',
'App\\SupportedApps\\Ttrss' => __DIR__ . '/../..' . '/app/SupportedApps/Ttrss.php',
'App\\SupportedApps\\Unifi' => __DIR__ . '/../..' . '/app/SupportedApps/Unifi.php',
'App\\SupportedApps\\ruTorrent' => __DIR__ . '/../..' . '/app/SupportedApps/ruTorrent.php',