Selaa lähdekoodia

Add uTorrent Homepage Item

root 4 vuotta sitten
vanhempi
commit
910a469b32

+ 10 - 2
api/classes/organizr.class.php

@@ -57,6 +57,7 @@ class Organizr
 	use TransmissionHomepageItem;
 	use UnifiHomepageItem;
 	use WeatherHomepageItem;
+        use uTorrentHomepageItem;
 	
 	// ===================================
 	// Organizr Version
@@ -4100,6 +4101,13 @@ class Organizr
 						$class .= ' faded';
 					}
 					break;
+                                case 'homepageOrderuTorrent':
+                                        $class = 'bg-qbit';
+                                        $image = 'plugins/images/tabs/utorrent.png';
+                                        if (!$this->config['homepageuTorrentEnabled']) {
+                                                $class .= ' faded';
+                                        }
+                                        break;
 				case 'homepageOrderrTorrent':
 					$class = 'bg-qbit';
 					$image = 'plugins/images/tabs/rTorrent.png';
@@ -4149,7 +4157,7 @@ class Organizr
 				case 'homepageOrderdownloader':
 					$class = 'bg-inverse';
 					$image = 'plugins/images/tabs/downloader.png';
-					if (!$this->config['jdownloaderCombine'] && !$this->config['sabnzbdCombine'] && !$this->config['nzbgetCombine'] && !$this->config['rTorrentCombine'] && !$this->config['delugeCombine'] && !$this->config['transmissionCombine'] && !$this->config['qBittorrentCombine']) {
+					if (!$this->config['jdownloaderCombine'] && !$this->config['sabnzbdCombine'] && !$this->config['nzbgetCombine'] && !$this->config['rTorrentCombine'] && !$this->config['delugeCombine'] && !$this->config['transmissionCombine'] && !$this->config['qBittorrentCombine'] && !$this->config['uTorrentCombine']) {
 						$class .= ' faded';
 					}
 					break;
@@ -6735,4 +6743,4 @@ class Organizr
 		return count($request) > 1 ? $results : $results[$firstKey];
 	}
 	
-}
+}

+ 15 - 1
api/config/default.php

@@ -170,6 +170,17 @@ return array(
 	'rTorrentUseCustomCertificate' => false,
 	'rTorrentLimit' => '200',
 	'rTorrentRefresh' => '60000',
+        'uTorrentURL' => '',
+        'uTorrentUsername' => '',
+        'uTorrentPassword' => '',
+        'uTorrentHideSeeding' => false,
+        'uTorrentHideCompleted' => false,
+        'uTorrentCombine' => false,
+        'uTorrentDisableCertCheck' => false,
+        'uTorrentUseCustomCertificate' => false,
+        'uTorrentRefresh' => '60000',
+        'uTorrentToken' => '',
+        'uTorrentCookie' => '',
 	'homepageJackettEnabled' => false,
 	'homepageJackettAuth' => '1',
 	'jackettURL' => '',
@@ -214,6 +225,8 @@ return array(
 	'homepageqBittorrentAuth' => '1',
 	'homepagerTorrentEnabled' => false,
 	'homepagerTorrentAuth' => '1',
+        'homepageuTorrentEnabled' => false,
+        'homepageuTorrentAuth' => '1',
 	'homepageNzbgetEnabled' => false,
 	'homepageNzbgetAuth' => '1',
 	'homepagePlexEnabled' => false,
@@ -279,6 +292,7 @@ return array(
 	'homepageOrderjellyfinnowplaying' => '29',
 	'homepageOrderjellyfinrecent' => '30',
 	'homepageOrderJackett' => '31',
+	'homepageOrderuTorrent' => '32',
 	'homepageShowStreamNames' => false,
 	'homepageShowStreamNamesAuth' => '1',
 	'homepageUseCustomStreamNames' => false,
@@ -543,4 +557,4 @@ return array(
 	'defaultSettingsTab' => '5',
 	'blacklisted' => '',
 	'blacklistedMessage' => 'You have been blacklisted from this site.'
-);
+);

+ 219 - 0
api/homepage/utorrent.php

@@ -0,0 +1,219 @@
+<?php
+
+trait uTorrentHomepageItem
+{
+	public function uTorrentSettingsArray($infoOnly = false)
+	{
+		$homepageInformation = [
+			'name' => 'uTorrent',
+			'enabled' => strpos('personal', $this->config['license']) !== false,
+			'image' => 'plugins/images/tabs/utorrent.png',
+			'category' => 'Downloader',
+			'settingsArray' => __FUNCTION__
+		];
+		if ($infoOnly) {
+			return $homepageInformation;
+		}
+		$homepageSettings = [
+			'debug' => true,
+			'settings' => [
+				'Enable' => [
+					$this->settingsOption('enable', 'homepageuTorrentEnabled'),
+					$this->settingsOption('auth', 'homepageuTorrentAuth'),
+				],
+				'Connection' => [
+					$this->settingsOption('url', 'uTorrentURL'),
+					$this->settingsOption('username', 'uTorrentUsername'),
+					$this->settingsOption('password', 'uTorrentPassword'),
+					$this->settingsOption('disable-cert-check', 'uTorrentDisableCertCheck'),
+					$this->settingsOption('use-custom-certificate', 'uTorrentUseCustomCertificate'),
+				],
+				'Misc Options' => [
+					$this->settingsOption('hide-seeding', 'uTorrentHideSeeding', ['label' => 'Hide Seeding']),
+					$this->settingsOption('hide-completed', 'uTorrentHideCompleted'),
+					$this->settingsOption('refresh', 'uTorrentRefresh'),
+					$this->settingsOption('combine', 'uTorrentCombine'),
+				],
+				'Test Connection' => [
+					$this->settingsOption('blank', null, ['label' => 'Please Save before Testing']),
+					$this->settingsOption('test', 'utorrent'),
+				]
+			]
+		];
+		return array_merge($homepageInformation, $homepageSettings);
+	}
+
+	public function uTorrentHomepagePermissions($key = null)
+	{
+		$permissions = [
+			'main' => [
+				'enabled' => [
+					'homepageuTorrentEnabled'
+				],
+				'auth' => [
+					'homepageuTorrentAuth'
+				],
+				'not_empty' => [
+					'uTorrentURL'
+				]
+			]
+		];
+		if (array_key_exists($key, $permissions)) {
+			return $permissions[$key];
+		} elseif ($key == 'all') {
+			return $permissions;
+		} else {
+			return [];
+		}
+	}
+
+        public function testConnectionuTorrent()
+        {
+                if (empty($this->config['uTorrentURL'])) {
+                        $this->setAPIResponse('error', 'uTorrent URL is not defined', 422);
+                        return false;
+                }
+                try {
+
+                        $response = $this->getuTorrentToken();
+
+                } catch (Requests_Exception $e) {
+                        $this->writeLog('error', 'uTorrent Connect Function - Error: ' . $e->getMessage(), 'SYSTEM');
+                        $this->setAPIResponse('error', $e->getMessage(), 500);
+                        return false;
+                }
+        }
+
+        public function homepageOrderuTorrent()
+        {
+                if ($this->homepageItemPermissions($this->uTorrentHomepagePermissions('main'))) {
+                        $loadingBox = ($this->config['uTorrentCombine']) ? '' : '<div class="white-box homepage-loading-box"><h2 class="text-center" lang="en">Loading Download Queue...</h2></div>';
+                        $builder = ($this->config['uTorrentCombine']) ? 'buildDownloaderCombined(\'utorrent\');' : '$("#' . __FUNCTION__ . '").html(buildDownloader("utorrent"));';
+                        return '
+                                <div id="' . __FUNCTION__ . '">
+                                        ' . $loadingBox . '
+                                        <script>
+                                // homepageOrderuTorrent
+                                ' . $builder . '
+                                homepageDownloader("utorrent", "' . $this->config['uTorrentRefresh'] . '");
+                                // End homepageOrderuTorrent
+                        </script>
+                                </div>
+                                ';
+                }
+        }
+
+        public function getuTorrentToken()
+        {
+		try {
+		        $tokenUrl = '/gui/token.html';
+		        $digest = $this->qualifyURL($this->config['uTorrentURL'], true);
+		        $url = $digest['scheme'] . '://' . $digest['host'] . $digest['port'] . $digest['path'] . $tokenUrl;
+	                $data = array('username' => $this->config['uTorrentUsername'], 'password' => $this->decrypt($this->config['uTorrentPassword']));
+	                $options = $this->requestOptions($url, null, $this->config['uTorrentDisableCertCheck'], $this->config['uTorrentUseCustomCertificate']);
+	                if ($this->config['uTorrentUsername'] !== '' && $this->decrypt($this->config['uTorrentPassword']) !== '') {
+		                $credentials = array('auth' => new Requests_Auth_Basic(array($this->config['uTorrentUsername'], $this->decrypt($this->config['uTorrentPassword']))));
+	                	$options = array_merge($options, $credentials);
+	                }
+	                $response = Requests::post($url, [], $data, $options);
+
+			$doc = new DOMDocument();
+			$doc->loadHTML($response->body);
+			$id = $doc->getElementById('token');
+			$uTorrentConfig = new stdClass();
+			$uTorrentConfig->uTorrentToken = $id->textContent;
+
+                        $reflection = new ReflectionClass($response->cookies);
+                        $cookie = $reflection->getProperty("cookies");
+                        $cookie->setAccessible(true);
+                        $cookie = $cookie->getValue($response->cookies);
+			if ($cookie['GUID']) {
+				$uTorrentConfig->uTorrentCookie = $cookie['GUID']->value;
+			}
+                        if ($uTorrentConfig->uTorrentToken || $uTorrentConfig->uTorrentCookie) {
+                                $this->updateConfigItems($uTorrentConfig);
+                        }
+
+		} catch (Requests_Exception $e) {
+	                $this->writeLog('error', 'uTorrent Connect Function - Error: ' . $e->getMessage(), 'SYSTEM');
+	                $this->setAPIResponse('error', $e->getMessage(), 500);
+                        return false;
+                }
+
+        }
+
+        public function getuTorrentHomepageQueue()
+        {
+                if (!$this->homepageItemPermissions($this->uTorrentHomepagePermissions('main'), true)) {
+                        return false;
+                }
+		try {
+			if (!$this->config['uTorrentToken'] || !$this->config['uTorrentCookie']) {
+				$this->getuTorrentToken();
+			}
+
+			$queryUrl = '/gui/?token='.$this->config['uTorrentToken'].'&list=1';
+                        $digest = $this->qualifyURL($this->config['uTorrentURL'], true);
+                        $url = $digest['scheme'] . '://' . $digest['host'] . $digest['port'] . $digest['path'] . $queryUrl;
+                        $options = $this->requestOptions($url, null, $this->config['uTorrentDisableCertCheck'], $this->config['uTorrentUseCustomCertificate']);
+                        if ($this->config['uTorrentUsername'] !== '' && $this->decrypt($this->config['uTorrentPassword']) !== '') {
+                                $credentials = array('auth' => new Requests_Auth_Basic(array($this->config['uTorrentUsername'], $this->decrypt($this->config['uTorrentPassword']))));
+                                $options = array_merge($options, $credentials);
+                        }
+                        $headers = array(
+                                'Cookie' => 'GUID=' . $this->config['uTorrentCookie']
+                        );
+                        $response = Requests::get($url, $headers, $options);
+			$httpResponse = $response->status_code;
+
+			if ($httpResponse == 200) {
+	                        $responseData = json_decode($response->body);
+				$keyArray = (array) $responseData->torrents;
+				//Populate values
+				$valueArray = array();
+				foreach ($keyArray as $keyArr) {
+					preg_match('/(?<Status>(\w+\s+)+)(?<Percentage>\d+.\d+.*)/', $keyArr[21], $matches);
+					$Status = str_replace(' ', '', $matches['Status']);
+					if ($this->config['uTorrentHideSeeding'] && $Status == "Seeding") {
+						// Do Nothing
+					} else if ($this->config['uTorrentHideCompleted'] && $Status == "Finished") {
+                                                // Do Nothing
+                                        } else {
+						$value = array(
+							'Name' => $keyArr[2],
+							'Labels' => $keyArr[11],
+							'Percent' => str_replace(' ', '', $matches['Percentage']),
+							'Status' => $Status,
+							'Availability' => $keyArr[4],
+							'Done' => $keyArr[5],
+							'Size' => $keyArr[3],
+							'upSpeed' => $keyArr[8],
+							'downSpeed' => $keyArr[9],
+							'Message' => $keyArr[21],
+						);
+						array_push($valueArray, $value);
+					}
+				}
+	                        $api['content']['queueItems'] = $valueArray;
+	                        $api['content'] = $api['content'] ?? false;
+	                        $this->setAPIResponse('success', null, 200, $api);
+	                        return $api;
+                        } else if ($httpResponse == 400) {
+	                        $this->writeLog('warn', 'uTorrent Token or Cookie Expired. Generating new session..', 'SYSTEM');
+				$this->getuTorrentToken();
+				$response = Requests::get($url, $headers, $options);
+				$responseData = json_decode($response->body);
+                                $api['content']['queueItems'] = json_encode($responseData->torrents);
+                                $api['content'] = $api['content'] ?? false;
+                                $this->setAPIResponse('success', null, 200, $api);
+				return $api;
+			}
+		} catch (Requests_Exception $e) {
+                        $this->writeLog('error', 'uTorrent Connect Function - Error: ' . $e->getMessage(), 'SYSTEM');
+                        $this->setAPIResponse('error', $e->getMessage(), 500);
+                        return false;
+                } 
+        }
+
+
+}

+ 1 - 1
api/pages/settings.php

@@ -390,4 +390,4 @@ function get_page_settings($Organizr)
 </form>
 <div id="editHomepageItemDiv"><div id="editHomepageItem" class=""></div></div>
 ';
-}
+}

+ 24 - 1
api/v2/routes/connectionTester.php

@@ -369,6 +369,29 @@ $app->post('/test/nzbget', function ($request, $response, $args) {
 		->withHeader('Content-Type', 'application/json;charset=UTF-8')
 		->withStatus($GLOBALS['responseCode']);
 	
+});
+$app->post('/test/utorrent', function ($request, $response, $args) {
+        /**
+         * @OA\Post(
+         *     security={{ "api_key":{} }},
+         *     tags={"test connection"},
+         *     path="/api/v2/test/utorrent",
+         *     summary="Test connection to uTorrent",
+         *     @OA\Response(response="200",description="Success",@OA\JsonContent(ref="#/components/schemas/success-message")),
+         *     @OA\Response(response="401",description="Unauthorized",@OA\JsonContent(ref="#/components/schemas/unauthorized-message")),
+         *     @OA\Response(response="400",description="Error",@OA\JsonContent(ref="#/components/schemas/error-message")),
+         *     @OA\Response(response="500",description="Error",@OA\JsonContent(ref="#/components/schemas/error-message")),
+         * )
+         */
+        $Organizr = ($request->getAttribute('Organizr')) ?? new Organizr();
+        if ($Organizr->qualifyRequest(1, true)) {
+                $Organizr->testConnectionuTorrent($Organizr->apiData($request));
+        }
+        $response->getBody()->write(jsonE($GLOBALS['api']));
+        return $response
+                ->withHeader('Content-Type', 'application/json;charset=UTF-8')
+                ->withStatus($GLOBALS['responseCode']);
+
 });
 $app->post('/test/deluge', function ($request, $response, $args) {
 	/**
@@ -530,4 +553,4 @@ $app->post('/test/tautulli', function ($request, $response, $args) {
 		->withHeader('Content-Type', 'application/json;charset=UTF-8')
 		->withStatus($GLOBALS['responseCode']);
 	
-});
+});

+ 9 - 1
api/v2/routes/homepage.php

@@ -208,6 +208,14 @@ $app->get('/homepage/qbittorrent/queue', function ($request, $response, $args) {
 		->withHeader('Content-Type', 'application/json;charset=UTF-8')
 		->withStatus($GLOBALS['responseCode']);
 });
+$app->get('/homepage/utorrent/queue', function ($request, $response, $args) {
+        $Organizr = ($request->getAttribute('Organizr')) ?? new Organizr();
+        $Organizr->getuTorrentHomepageQueue();
+        $response->getBody()->write(jsonE($GLOBALS['api']));
+        return $response
+                ->withHeader('Content-Type', 'application/json;charset=UTF-8')
+                ->withStatus($GLOBALS['responseCode']);
+});
 $app->get('/homepage/jdownloader/queue', function ($request, $response, $args) {
 	$Organizr = ($request->getAttribute('Organizr')) ?? new Organizr();
 	$Organizr->getJdownloaderHomepageQueue();
@@ -439,4 +447,4 @@ $app->get('/homepage/trakt/calendar', function ($request, $response, $args) {
 	return $response
 		->withHeader('Content-Type', 'application/json;charset=UTF-8')
 		->withStatus($GLOBALS['responseCode']);
-});
+});

+ 46 - 4
js/functions.js

@@ -2169,6 +2169,8 @@ function checkTabHomepageItem(id, name, url, urlLocal){
         addEditHomepageItem(id,'qBittorrent');
     }else if(name.includes('rtorrent') || url.includes('rtorrent') || urlLocal.includes('rtorrent')){
         addEditHomepageItem(id,'rTorrent');
+    }else if(name.includes('utorrent') || url.includes('utorrent') || urlLocal.includes('utorrent')){
+        addEditHomepageItem(id,'utorrent');
     }else if(name.includes('deluge') || url.includes('deluge') || urlLocal.includes('deluge')){
         addEditHomepageItem(id,'Deluge');
     }else if(name.includes('ombi') || url.includes('ombi') || urlLocal.includes('ombi')){
@@ -6051,6 +6053,37 @@ function buildDownloaderItem(array, source, type='none'){
                 </tr>
                 `;
             });
+            break;
+        case 'utorrent':
+            if(array.content === false){
+                queue = '<tr><td class="max-texts" lang="en">Connection Error to ' + source + '</td></tr>';
+                break;
+            }
+            if(array.content.queueItems == 0){
+                queue = '<tr><td class="max-texts" lang="en">Nothing in queue</td></tr>';
+            }
+            $.each(array.content.queueItems, function(i,v) {
+                console.log(v);
+		count = count + 1;
+                var upload = v.upSpeed !== '' ? humanFileSize(v.upSpeed,false) : "0 B";
+                var download = v.downSpeed !== '' ? humanFileSize(v.downSpeed,false) : "0 B";
+		var size = v.Size !== '' ? humanFileSize(v.Size,false) : "0 B";
+                queue += `
+                <tr>
+                    <td class="max-texts"><span class="tooltip-info" data-toggle="tooltip" data-placement="right" title="">`+v.Name+`</span></td>
+		    <td class="hidden-xs utorrent-`+cleanClass(v.Status)+`">`+v.Status+`</td>
+                    <td class="hidden-xs"><span class="label label-info">`+v.Labels+`</span></td>
+		    <td class="hidden-xs"><span class="tooltip-info" data-toggle="tooltip" data-placement="right" title="" data-original-title="`+download+`"><i class="fa fa-download"></i>&nbsp;`+download+`</span></td>
+                    <td class="hidden-xs"><span class="tooltip-info" data-toggle="tooltip" data-placement="right" title="" data-original-title="`+upload+`"><i class="fa fa-upload"></i>&nbsp;`+upload+`</span></td>
+		    <td class="hidden-xs">`+size+`</td>
+                    <td class="text-right">
+                        <div class="progress progress-lg m-b-0">
+                            <div class="progress-bar progress-bar-info" style="width: `+v.Percent+`;" role="progressbar">`+v.Percent+`</div>
+                        </div>
+                    </td>
+                </tr>
+                `;
+            });
             break;
 		case 'sonarr':
 			if(array.content === false){
@@ -6246,6 +6279,9 @@ function buildDownloader(source){
         case 'transmission':
         case 'qBittorrent':
         case 'deluge':
+	case 'utorrent':
+            var queue = true;
+            break;
         case 'rTorrent':
 	    case 'sonarr':
 	    case 'radarr':
@@ -6345,6 +6381,9 @@ function buildDownloaderCombined(source){
             var queue = true;
             var history = true;
             break;
+        case 'utorrent':
+            var queue = true;
+            break;
         case 'transmission':
         case 'qBittorrent':
         case 'deluge':
@@ -7049,9 +7088,12 @@ function homepageDownloader(type, timeout){
 		case 'deluge':
 			var action = 'getDeluge';
 			break;
-        case 'rTorrent':
-            var action = 'getrTorrent';
-            break;
+	        case 'rTorrent':
+			var action = 'getrTorrent';
+			break;
+                case 'utorrent':
+                        var action = 'getutorrent';
+                        break;
 		default:
 
 	}
@@ -10923,4 +10965,4 @@ function launch(){
 			orgErrorAlert('<h3>Webserver Error:</h3>' + xhr.responseText);
 		}
 	});
-}
+}

BIN
plugins/images/tabs/Library.png


BIN
plugins/images/tabs/admin-tools.png


BIN
plugins/images/tabs/mantis.png


BIN
plugins/images/tabs/tools.png


BIN
plugins/images/tabs/world.png