'rTorrent',
'enabled' => strpos('personal', $this->config['license']) !== false,
'image' => 'plugins/images/tabs/rTorrent.png',
'category' => 'Downloader',
'settingsArray' => __FUNCTION__
];
if ($infoOnly) {
return $homepageInformation;
}
$xmlStatus = (extension_loaded('xmlrpc')) ? 'Installed' : 'Not Installed';
$homepageSettings = array(
'settings' => array(
'FYI' => array(
array(
'type' => 'html',
'label' => '',
'override' => 12,
'html' => '
ATTENTION
This module requires XMLRPC
Status: [ ' . $xmlStatus . ' ]
Note about API URL
Organizr appends the url with /RPC2 unless the URL ends in .php
Possible URLs:
http://localhost:8080
https://domain.site/xmlrpc.php
https://seedbox.site/rutorrent/plugins/httprpc/action.php
'
)
),
'Enable' => array(
array(
'type' => 'switch',
'name' => 'homepagerTorrentEnabled',
'label' => 'Enable',
'value' => $this->config['homepagerTorrentEnabled']
),
array(
'type' => 'select',
'name' => 'homepagerTorrentAuth',
'label' => 'Minimum Authentication',
'value' => $this->config['homepagerTorrentAuth'],
'options' => $this->groupOptions
)
),
'Connection' => array(
array(
'type' => 'input',
'name' => 'rTorrentURL',
'label' => 'URL',
'value' => $this->config['rTorrentURL'],
'help' => 'Please make sure to use local IP address and port - You also may use local dns name too.',
'placeholder' => 'http(s)://hostname:port'
),
array(
'type' => 'input',
'name' => 'rTorrentURLOverride',
'label' => 'rTorrent API URL Override',
'value' => $this->config['rTorrentURLOverride'],
'help' => 'Only use if you cannot connect. Please make sure to use local IP address and port - You also may use local dns name too.',
'placeholder' => 'http(s)://hostname:port/xmlrpc'
),
array(
'type' => 'input',
'name' => 'rTorrentUsername',
'label' => 'Username',
'value' => $this->config['rTorrentUsername']
),
array(
'type' => 'password',
'name' => 'rTorrentPassword',
'label' => 'Password',
'value' => $this->config['rTorrentPassword']
),
array(
'type' => 'switch',
'name' => 'rTorrentDisableCertCheck',
'label' => 'Disable Certificate Check',
'value' => $this->config['rTorrentDisableCertCheck']
),
),
'Misc Options' => array(
array(
'type' => 'switch',
'name' => 'rTorrentHideSeeding',
'label' => 'Hide Seeding',
'value' => $this->config['rTorrentHideSeeding']
), array(
'type' => 'switch',
'name' => 'rTorrentHideCompleted',
'label' => 'Hide Completed',
'value' => $this->config['rTorrentHideCompleted']
),
array(
'type' => 'select',
'name' => 'rTorrentSortOrder',
'label' => 'Order',
'value' => $this->config['rTorrentSortOrder'],
'options' => $this->rTorrentSortOptions()
),
array(
'type' => 'select',
'name' => 'rTorrentRefresh',
'label' => 'Refresh Seconds',
'value' => $this->config['rTorrentRefresh'],
'options' => $this->timeOptions()
),
array(
'type' => 'number',
'name' => 'rTorrentLimit',
'label' => 'Item Limit',
'value' => $this->config['rTorrentLimit'],
),
array(
'type' => 'switch',
'name' => 'rTorrentCombine',
'label' => 'Add to Combined Downloader',
'value' => $this->config['rTorrentCombine']
),
),
'Test Connection' => array(
array(
'type' => 'blank',
'label' => 'Please Save before Testing'
),
array(
'type' => 'button',
'label' => '',
'icon' => 'fa fa-flask',
'class' => 'pull-right',
'text' => 'Test Connection',
'attr' => 'onclick="testAPIConnection(\'rtorrent\')"'
),
)
)
);
return array_merge($homepageInformation, $homepageSettings);
}
public function testConnectionRTorrent()
{
if (empty($this->config['rTorrentURL']) && empty($this->config['rTorrentURLOverride'])) {
$this->setAPIResponse('error', 'rTorrent URL is not defined', 422);
return false;
}
try {
$digest = (empty($this->config['rTorrentURLOverride'])) ? $this->qualifyURL($this->config['rTorrentURL'], true) : $this->qualifyURL($this->checkOverrideURL($this->config['rTorrentURL'], $this->config['rTorrentURLOverride']), true);
$extraPath = (strpos($this->config['rTorrentURL'], '.php') !== false) ? '' : '/RPC2';
$extraPath = (empty($this->config['rTorrentURLOverride'])) ? $extraPath : '';
$url = $digest['scheme'] . '://' . $digest['host'] . $digest['port'] . $digest['path'] . $extraPath;
$options = ($this->localURL($url, $this->config['rTorrentDisableCertCheck'])) ? array('verify' => false) : array();
if ($this->config['rTorrentUsername'] !== '' && $this->decrypt($this->config['rTorrentPassword']) !== '') {
$credentials = array('auth' => new Requests_Auth_Digest(array($this->config['rTorrentUsername'], $this->decrypt($this->config['rTorrentPassword']))));
$options = array_merge($options, $credentials);
}
$data = xmlrpc_encode_request("system.listMethods", null);
$response = Requests::post($url, array(), $data, $options);
if ($response->success) {
$methods = xmlrpc_decode(str_replace('i8>', 'i4>', $response->body));
if (count($methods) !== 0) {
$this->setAPIResponse('success', 'API Connection succeeded', 200);
return true;
}
}
$this->setAPIResponse('error', 'rTorrent error occurred', 500);
return false;
} catch
(Requests_Exception $e) {
$this->writeLog('error', 'rTorrent Connect Function - Error: ' . $e->getMessage(), 'SYSTEM');
$this->setAPIResponse('error', $e->getMessage(), 500);
return false;
}
}
public function rTorrentHomepagePermissions($key = null)
{
$permissions = [
'main' => [
'enabled' => [
'homepagerTorrentEnabled'
],
'auth' => [
'homepagerTorrentAuth'
],
'not_empty' => []
]
];
if (array_key_exists($key, $permissions)) {
return $permissions[$key];
} elseif ($key == 'all') {
return $permissions;
} else {
return [];
}
}
public function homepageOrderrTorrent()
{
if ($this->homepageItemPermissions($this->rTorrentHomepagePermissions('main'))) {
$loadingBox = ($this->config['rTorrentCombine']) ? '' : 'Loading Download Queue...
';
$builder = ($this->config['rTorrentCombine']) ? 'buildDownloaderCombined(\'rTorrent\');' : '$("#' . __FUNCTION__ . '").html(buildDownloader("rTorrent"));';
return '
' . $loadingBox . '
';
}
}
public function checkOverrideURL($url, $override)
{
if (strpos($override, $url) !== false) {
return $override;
} else {
return $url . $override;
}
}
public function rTorrentStatus($completed, $state, $status)
{
if ($completed && $state && $status == 'seed') {
$state = 'Seeding';
} elseif (!$completed && !$state && $status == 'leech') {
$state = 'Stopped';
} elseif (!$completed && $state && $status == 'leech') {
$state = 'Downloading';
} elseif ($completed && !$state && $status == 'seed') {
$state = 'Finished';
}
return ($state) ? $state : $status;
}
public function getRTorrentHomepageQueue()
{
if (empty($this->config['rTorrentURL']) && empty($this->config['rTorrentURLOverride'])) {
$this->setAPIResponse('error', 'rTorrent URL is not defined', 422);
return false;
}
if (!$this->homepageItemPermissions($this->rTorrentHomepagePermissions('main'), true)) {
return false;
}
try {
if ($this->config['rTorrentLimit'] == '0') {
$this->config['rTorrentLimit'] = '1000';
}
$torrents = array();
$digest = (empty($this->config['rTorrentURLOverride'])) ? $this->qualifyURL($this->config['rTorrentURL'], true) : $this->qualifyURL($this->checkOverrideURL($this->config['rTorrentURL'], $this->config['rTorrentURLOverride']), true);
$extraPath = (strpos($this->config['rTorrentURL'], '.php') !== false) ? '' : '/RPC2';
$extraPath = (empty($this->config['rTorrentURLOverride'])) ? $extraPath : '';
$url = $digest['scheme'] . '://' . $digest['host'] . $digest['port'] . $digest['path'] . $extraPath;
$options = ($this->localURL($url, $this->config['rTorrentDisableCertCheck'])) ? array('verify' => false) : array();
if ($this->config['rTorrentUsername'] !== '' && $this->decrypt($this->config['rTorrentPassword']) !== '') {
$credentials = array('auth' => new Requests_Auth_Digest(array($this->config['rTorrentUsername'], $this->decrypt($this->config['rTorrentPassword']))));
$options = array_merge($options, $credentials);
}
$data = xmlrpc_encode_request("d.multicall2", array(
"",
"main",
"d.name=",
"d.base_path=",
"d.up.total=",
"d.size_bytes=",
"d.down.total=",
"d.completed_bytes=",
"d.connection_current=",
"d.down.rate=",
"d.up.rate=",
"d.timestamp.started=",
"d.state=",
"d.group.name=",
"d.hash=",
"d.complete=",
"d.ratio=",
"d.chunk_size=",
"f.size_bytes=",
"f.size_chunks=",
"f.completed_chunks=",
"d.custom=",
"d.custom1=",
"d.custom2=",
"d.custom3=",
"d.custom4=",
"d.custom5=",
), array());
$response = Requests::post($url, array(), $data, $options);
if ($response->success) {
$torrentList = xmlrpc_decode(str_replace('i8>', 'string>', $response->body));
if (is_array($torrentList)) {
foreach ($torrentList as $key => $value) {
$tempStatus = $this->rTorrentStatus($value[13], $value[10], $value[6]);
if ($tempStatus == 'Seeding' && $this->config['rTorrentHideSeeding']) {
//do nothing
} elseif ($tempStatus == 'Finished' && $this->config['rTorrentHideCompleted']) {
//do nothing
} else {
$torrents[$key] = array(
'name' => $value[0],
'base' => $value[1],
'upTotal' => $value[2],
'size' => $value[3],
'downTotal' => $value[4],
'downloaded' => $value[5],
'connectionState' => $value[6],
'leech' => $value[7],
'seed' => $value[8],
'date' => $value[9],
'state' => ($value[10]) ? 'on' : 'off',
'group' => $value[11],
'hash' => $value[12],
'complete' => ($value[13]) ? 'yes' : 'no',
'ratio' => $value[14],
'label' => $value[20],
'status' => $tempStatus,
'temp' => $value[16] . ' - ' . $value[17] . ' - ' . $value[18],
'custom' => $value[19] . ' - ' . $value[20] . ' - ' . $value[21],
'custom2' => $value[22] . ' - ' . $value[23] . ' - ' . $value[24],
);
}
}
}
if (count($torrents) !== 0) {
usort($torrents, function ($a, $b) {
$direction = substr($this->config['rTorrentSortOrder'], -1);
$sort = substr($this->config['rTorrentSortOrder'], 0, strlen($this->config['rTorrentSortOrder']) - 1);
switch ($direction) {
case 'a':
return $a[$sort] <=> $b[$sort];
break;
case 'd':
return $b[$sort] <=> $a[$sort];
break;
default:
return $b['date'] <=> $a['date'];
}
});
$torrents = array_slice($torrents, 0, $this->config['rTorrentLimit']);
}
$api['content']['queueItems'] = $torrents;
$api['content']['historyItems'] = false;
}
} catch
(Requests_Exception $e) {
$this->writeLog('error', 'rTorrent Connect Function - Error: ' . $e->getMessage(), 'SYSTEM');
$this->setAPIResponse('error', $e->getMessage(), 500);
return false;
};
$api['content'] = isset($api['content']) ? $api['content'] : false;
$this->setAPIResponse('success', null, 200, $api);
return $api;
}
}