Browse Source

Added Unifi to homepage

CauseFX 6 years ago
parent
commit
aca4639816

+ 11 - 2
api/config/default.php

@@ -157,7 +157,8 @@ return array(
 	'homepageOrderrTorrent' => '15',
 	'homepageOrderdownloader' => '16',
 	'homepageOrderhealthchecks' => '17',
-    "homepageOrderjdownloader" => '18',
+	'homepageOrderjdownloader' => '18',
+	'homepageOrderunifi' => '19',
 	'homepageShowStreamNames' => false,
 	'homepageShowStreamNamesAuth' => '1',
 	'homepageStreamRefresh' => '60000',
@@ -243,5 +244,13 @@ return array(
 	'authProxyEnabled' => false,
 	'authProxyHeaderName' => '',
 	'authProxyWhitelist' => '',
-	'ignoreTFALocal' => false
+	'ignoreTFALocal' => false,
+	'unifiURL' => '',
+	'unifiUsername' => '',
+	'unifiPassword' => '',
+	'unifiSiteName' => '',
+	'unifiCookie' => '',
+	'homepageUnifiEnabled' => 'false',
+	'homepageUnifiAuth' => '1',
+	'homepageUnifiRefresh' => '600000'
 );

+ 71 - 0
api/functions/homepage-connect-functions.php

@@ -57,6 +57,9 @@ function homepageConnect($array)
 		case 'getHealthChecks':
 			return (qualifyRequest($GLOBALS['homepageHealthChecksAuth'])) ? getHealthChecks($array['data']['tags']) : false;
 			break;
+		case 'getUnifi':
+			return unifiConnect();
+			break;
 		default:
 			# code...
 			break;
@@ -2328,9 +2331,77 @@ function getOmbiRequests($type = "both", $limit = 50)
 	return $api;
 }
 
+function unifiConnect()
+{
+	if ($GLOBALS['homepageUnifiEnabled'] && !empty($GLOBALS['unifiURL']) && !empty($GLOBALS['unifiSiteName']) && !empty($GLOBALS['unifiCookie']) && !empty($GLOBALS['unifiUsername']) && !empty($GLOBALS['unifiPassword']) && qualifyRequest($GLOBALS['homepageUnifiAuth'])) {
+		$api['content']['unifi'] = array();
+		$url = qualifyURL($GLOBALS['unifiURL']);
+		$url = $url . '/api/s/' . $GLOBALS['unifiSiteName'] . '/stat/health';
+		try {
+			$options = array('verify' => false, 'verifyname' => false, 'follow_redirects' => false);
+			$headers = array(
+				'cookie' => $GLOBALS['unifiCookie']
+			);
+			$response = Requests::get($url, $headers, $options);
+			if ($response->success) {
+				$api['content']['unifi'] = json_decode($response->body, true);
+			}
+		} catch (Requests_Exception $e) {
+			writeLog('error', 'Unifi Connect Function - Error: ' . $e->getMessage(), 'SYSTEM');
+		};
+		$api['content']['unifi'] = isset($api['content']['unifi']) ? $api['content']['unifi'] : false;
+		return $api;
+	}
+	return false;
+}
+
 function testAPIConnection($array)
 {
 	switch ($array['data']['action']) {
+		case 'unifiCookie':
+			if (!empty($GLOBALS['unifiURL'])  && !empty($GLOBALS['unifiUsername'])  && !empty($GLOBALS['unifiPassword'])) {
+				$url = qualifyURL($GLOBALS['unifiURL']);
+				try {
+					$options = array('verify' => false, 'verifyname' => false, 'follow_redirects' => false);
+					$data = array(
+						'username' => $GLOBALS['unifiUsername'],
+						'password' => decrypt($GLOBALS['unifiPassword']),
+						'remember' => true,
+						'strict' => true
+					);
+					$response = Requests::post($url . '/api/login', array(), json_encode($data), $options);
+					if ($response->success) {
+						$cookie['unifises'] = ($response->cookies['unifises']->value) ?? false;
+						$cookie['csrf_token'] = ($response->cookies['csrf_token']->value) ?? false;
+						return $cookie;
+					}else{
+						return false;
+					}
+				} catch (Requests_Exception $e) {
+					writeLog('error', 'Unifi Connect Function - Error: ' . $e->getMessage(), 'SYSTEM');
+				};
+			}
+			break;
+		case 'unifiSite':
+			if (!empty($GLOBALS['unifiURL'])  && !empty($GLOBALS['unifiCookie']) && !empty($GLOBALS['unifiUsername'])  && !empty($GLOBALS['unifiPassword'])) {
+				$url = qualifyURL($GLOBALS['unifiURL']);
+				try {
+					$options = array('verify' => false, 'verifyname' => false, 'follow_redirects' => false);
+					$headers = array(
+						'cookie' => $GLOBALS['unifiCookie']
+					);
+					$response = Requests::get($url . '/api/self/sites', $headers, $options);
+					if ($response->success) {
+						$body = json_decode($response->body, true);
+						return $body;
+					}else{
+						return false;
+					}
+				} catch (Requests_Exception $e) {
+					writeLog('error', 'Unifi Connect Function - Error: ' . $e->getMessage(), 'SYSTEM');
+				};
+			}
+			break;
 		case 'ombi':
 			if (!empty($GLOBALS['ombiURL']) && !empty($GLOBALS['ombiToken'])) {
 				$url = qualifyURL($GLOBALS['ombiURL']);

+ 121 - 0
api/functions/homepage-functions.php

@@ -21,6 +21,7 @@ function homepageOrder()
 		"homepageOrderrTorrent" => $GLOBALS['homepageOrderrTorrent'],
 		"homepageOrderdownloader" => $GLOBALS['homepageOrderdownloader'],
 		"homepageOrderhealthchecks" => $GLOBALS['homepageOrderhealthchecks'],
+		"homepageOrderunifi" => $GLOBALS['homepageOrderunifi'],
 	);
 	asort($homepageOrder);
 	return $homepageOrder;
@@ -318,6 +319,18 @@ function buildHomepageItem($homepageItem)
 				';
 			}
 			break;
+		case 'homepageOrderunifi':
+			if ($GLOBALS['homepageUnifiEnabled'] && qualifyRequest($GLOBALS['homepageUnifiAuth'])) {
+				$item .= '<div class="white-box"><h2 class="text-center" lang="en">Loading Unifi...</h2></div>';
+				$item .= '
+				<script>
+				// Unifi
+				homepageUnifi("' . $GLOBALS['homepageHealthChecksRefresh'] . '");
+				// End Unifi
+				</script>
+				';
+			}
+			break;
 		default:
 			# code...
 			break;
@@ -2201,6 +2214,107 @@ function getHomepageList()
 				)
 			)
 		),
+		array(
+			'name' => 'Unifi',
+			'enabled' => true,
+			'image' => 'plugins/images/tabs/ubnt.png',
+			'category' => 'Monitor',
+			'settings' => array(
+				'Enable' => array(
+					array(
+						'type' => 'switch',
+						'name' => 'homepageUnifiEnabled',
+						'label' => 'Enable',
+						'value' => $GLOBALS['homepageUnifiEnabled']
+					),
+					array(
+						'type' => 'select',
+						'name' => 'homepageUnifiAuth',
+						'label' => 'Minimum Authentication',
+						'value' => $GLOBALS['homepageUnifiAuth'],
+						'options' => $groups
+					)
+				),
+				'Connection' => array(
+					array(
+						'type' => 'input',
+						'name' => 'unifiURL',
+						'label' => 'URL',
+						'value' => $GLOBALS['unifiURL'],
+						'help' => 'URL for Unifi',
+						'placeholder' => 'Unifi API URL'
+					),
+					array(
+						'type' => 'blank',
+						'label' => ''
+					),
+					array(
+						'type' => 'input',
+						'name' => 'unifiUsername',
+						'label' => 'Username',
+						'value' => $GLOBALS['unifiUsername']
+					),
+					array(
+						'type' => 'password',
+						'name' => 'unifiPassword',
+						'label' => 'Password',
+						'value' => $GLOBALS['unifiPassword']
+					),
+					array(
+						'type' => 'input',
+						'name' => 'unifiCookie',
+						'label' => 'Cookie',
+						'value' => $GLOBALS['unifiCookie'],
+						'help' => 'Cookie for Unifi - Save username and password before clicking get cookie button',
+						'placeholder' => 'Click help button'
+					),
+					array(
+						'type' => 'button',
+						'label' => 'Grab Unifi Cookie',
+						'icon' => 'fa fa-globe',
+						'text' => 'Get Unifi Cookie',
+						'attr' => 'onclick="getUnifiCookie(\'unifiCookie\')"'
+					),
+					array(
+						'type' => 'input',
+						'name' => 'unifiSiteName',
+						'label' => 'Site Name',
+						'value' => $GLOBALS['unifiSiteName'],
+						'help' => 'Site Name - not Site ID nor Site Description',
+					),
+					array(
+						'type' => 'button',
+						'label' => 'Grab Unifi Site',
+						'icon' => 'fa fa-building',
+						'text' => 'Get Unifi Site',
+						'attr' => 'onclick="getUnifiSite(\'unifiSite\')"'
+					),
+				),
+				'Misc Options' => array(
+					array(
+						'type' => 'select',
+						'name' => 'homepageUnifiRefresh',
+						'label' => 'Refresh Seconds',
+						'value' => $GLOBALS['homepageUnifiRefresh'],
+						'options' => optionTime()
+					),
+				),
+				'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(\'unifi\')"'
+					),
+				)
+			)
+		),
 		array(
 			'name' => 'HealthChecks',
 			'enabled' => true,
@@ -2451,6 +2565,13 @@ function buildHomepageSettings()
 					$class .= ' faded';
 				}
 				break;
+			case 'homepageOrderunifi':
+				$class = 'bg-info';
+				$image = 'plugins/images/tabs/ubnt.png';
+				if (!$GLOBALS['homepageUnifiEnabled']) {
+					$class .= ' faded';
+				}
+				break;
 			default:
 				$class = 'blue-bg';
 				$image = '';

+ 203 - 4
js/functions.js

@@ -1005,7 +1005,7 @@ function buildPluginsItem(array){
                 </div>
                 <div class="panel-wrapper collapse in" aria-expanded="true">
                     <div class="panel-body bg-org">
-                    <fieldset id="`+v.idPrefix+`-settings-items" style="border:0;" class=""></fieldset>
+                        <fieldset id="`+v.idPrefix+`-settings-items" style="border:0;" class=""><h2>Loading...</h2></fieldset>
                     </div>
                     <div class="clearfix"></div>
                 </div>
@@ -2547,10 +2547,10 @@ function buildFrameContainer(name,url,type){
 function buildInternalContainer(name,url,type){
 	return `<div id="internal-`+cleanClass(name)+`" data-type="`+type+`" class="internal-container frame-`+cleanClass(name)+` hidden" data-url="`+url+`" data-name="`+cleanClass(name)+`"></div>`;
 }
-function buildMenuList(name,url,type,icon,ping=null){
+function buildMenuList(name,url,type,icon,ping=null,category_id = null,group_id = null){
     var ping = (ping !== null) ? `<small class="menu-`+cleanClass(ping)+`-ping-ms hidden-xs label label-rouded label-inverse pull-right pingTime hidden">
 </small><div class="menu-`+cleanClass(ping)+`-ping" data-tab-name="`+name+`" data-previous-state=""></div>` : '';
-	return `<li class="allTabsList" id="menu-`+cleanClass(name)+`" data-tab-name="`+cleanClass(name)+`" type="`+type+`" data-url="`+url+`"><a class="waves-effect"  onclick="tabActions(event,'`+cleanClass(name)+`',`+type+`);">`+iconPrefix(icon)+`<span class="hide-menu elip sidebar-tabName">`+name+`</span>`+ping+`</a></li>`;
+	return `<li class="allTabsList" id="menu-`+cleanClass(name)+`" data-tab-name="`+cleanClass(name)+`" type="`+type+`" data-group-id="`+group_id+`" data-category-id="`+category_id+`" data-url="`+url+`"><a class="waves-effect"  onclick="tabActions(event,'`+cleanClass(name)+`',`+type+`);">`+iconPrefix(icon)+`<span class="hide-menu elip sidebar-tabName">`+name+`</span>`+ping+`</a></li>`;
 }
 function tabProcess(arrayItems) {
 	var iFrameList = '';
@@ -2577,7 +2577,7 @@ function tabProcess(arrayItems) {
                     defaultTabName = cleanClass(v.name);
                     defaultTabType = v.type;
                 }
-                var menuList = buildMenuList(v.name,v.access_url,v.type,v.image,v.ping_url);
+                var menuList = buildMenuList(v.name,v.access_url,v.type,v.image,v.ping_url, v.category_id, v.group_id);
                 if(v.category_id === 0){
                     if(activeInfo.settings.misc.unsortedTabs === 'top'){
                         $(menuList).prependTo($('#side-menu'));
@@ -5671,6 +5671,104 @@ function buildHealthChecks(array){
 	<div class="clearfix"></div>
 	` : '';
 }
+function buildUnifi(array){
+    if(array === false){ return ''; }
+    var items = (typeof array.content.unifi.data !== 'undefined') ? array.content.unifi.data.length : false;
+    return (items) ? `
+	<div id="allUnifi">
+		<div class="row">
+		    <div class="col-md-12">
+		        <h4 class="pull-left"><span lang="en">Unifi</span> : </h4><h4 class="pull-left">&nbsp;</h4>
+		        <hr class="hidden-xs">
+		    </div>
+			<div class="clearfix"></div>
+		    <!-- .cards -->
+		    <div class="unifiCards">
+		        `+buildUnifiItem(array.content.unifi.data)+`
+			</div>
+		    <!-- /.cards-->
+		</div>
+	</div>
+	<div class="clearfix"></div>
+	` : '';
+}
+function buildUnifiItem(array){
+    var items = '';
+    $.each(array, function(i,v) {
+        console.log(v);
+        var name = (typeof v.subsystem !== 'undefined') ? v.subsystem : '';
+        var stats = {};
+        var panelColor = '';
+        switch (name) {
+            case 'wlan':
+                panelColor = 'info';
+                stats['clients'] = v.num_user;
+                stats['tx'] = v['tx_bytes-r'];
+                stats['rx'] = v['rx_bytes-r'];
+                break;
+            case 'wan':
+                panelColor = 'success';
+                stats['IP'] = v.wan_ip;
+                stats['tx'] = v['tx_bytes-r'];
+                stats['rx'] = v['rx_bytes-r'];
+                break;
+            case 'lan':
+                panelColor = 'primary';
+                stats['clients'] = v.num_user;
+                stats['tx'] = v['tx_bytes-r'];
+                stats['rx'] = v['rx_bytes-r'];
+                break;
+            case 'www':
+                panelColor = 'warning';
+                stats['drops'] = v.drops;
+                stats['latency'] = v.latency;
+                stats['uptime'] = v.uptime;
+                stats['tx'] = v['tx_bytes-r'];
+                stats['rx'] = v['rx_bytes-r'];
+                break;
+            case 'vpn':
+                panelColor = 'inverse';
+                stats['clients'] = v.remote_user_num_active;
+                stats['tx'] = v.remote_user_tx_bytes;
+                stats['rx'] = v.remote_user_rx_bytes;
+                break;
+            default:
+        }
+        var statItems = '';
+       console.log(statItems);
+        $.each(stats, function(istat,vstat) {
+            statItems += `
+                <div class="stat-item">
+                    <h6 class="text-uppercase">`+istat+`</h6>
+                    <b>`+vstat+`</b>
+                </div>
+                `;
+        });
+        items += `
+            <!--<div class="col-lg-4 col-md-6">
+                <div class="white-box">
+                    <h3 class="box-title">`+name+`</h3>
+                    <div class="stats-row">
+                        `+statItems+`
+                    </div>
+                </div>
+            </div>-->
+            <div class="col-lg-4 col-md-6">
+                <div class="panel panel-`+panelColor+`">
+                    <div class="panel-heading"> <span class="text-uppercase">`+name+`</span>
+                        <div class="pull-right"><a href="#" data-perform="panel-collapse"><i class="ti-minus"></i></a> <a href="#" data-perform="panel-dismiss"><i class="ti-close"></i></a> </div>
+                    </div>
+                    <div class="panel-wrapper collapse in" aria-expanded="true">
+                        <div class="panel-body">
+                           `+statItems+`
+                        </div>
+                    </div>
+                </div>
+            </div>
+        `;
+    });
+    return items;
+}
 function healthCheckIcon(tags){
     var allTags = tags.split(' ');
     var useIcon = '';
@@ -5774,6 +5872,28 @@ function homepageHealthChecks(tags, timeout){
     if(typeof timeouts[timeoutTitle] !== 'undefined'){ clearTimeout(timeouts[timeoutTitle]); }
     timeouts[timeoutTitle] = setTimeout(function(){ homepageHealthChecks(tags,timeout); }, timeout);
 }
+function homepageUnifi(timeout){
+    var timeout = (typeof timeout !== 'undefined') ? timeout : activeInfo.settings.homepage.refresh.homepageUnifiRefresh;
+    organizrAPI('POST','api/?v1/homepage/connect',{action:'getUnifi'}).success(function(data) {
+        try {
+            var response = JSON.parse(data);
+        }catch(e) {
+            console.log(e + ' error: ' + data);
+            orgErrorAlert('<h4>' + e + '</h4>' + formatDebug(data));
+            return false;
+        }
+        document.getElementById('homepageOrderunifi').innerHTML = '';
+        console.log(response.data);
+        if(response.data !== null){
+            $('#homepageOrderunifi').html(buildUnifi(response.data));
+        }
+    }).fail(function(xhr) {
+        console.error("Organizr Function: API Connection Failed");
+    });
+    var timeoutTitle = 'Unifi-Homepage';
+    if(typeof timeouts[timeoutTitle] !== 'undefined'){ clearTimeout(timeouts[timeoutTitle]); }
+    timeouts[timeoutTitle] = setTimeout(function(){ homepageUnifi(timeout); }, timeout);
+}
 function homepageDownloader(type, timeout){
 	var timeout = (typeof timeout !== 'undefined') ? timeout : activeInfo.settings.homepage.refresh.homepageDownloadRefresh;
 	//if(isHidden()){ return; }
@@ -5984,6 +6104,85 @@ function testAPIConnection(service, data = ''){
         message('',' Organizr Error',activeInfo.settings.notifications.position,'#FFF','error','10000');
     });
 }
+function getUnifiCookie(service, data = ''){
+    messageSingle('',' Grabbing now...',activeInfo.settings.notifications.position,'#FFF','info','10000');
+    organizrAPI('POST','api/?v1/test/api/connection',{action:service, data:data}).success(function(data) {
+        try {
+            var response = JSON.parse(data);
+        }catch(e) {
+            console.log(e + ' error: ' + data);
+            orgErrorAlert('<h4>' + e + '</h4>' + formatDebug(data));
+            return false;
+        }
+        if(response.data !== false){
+            var unifises = response.data.unifises;
+            var csrf_token = response.data.csrf_token;
+            var cookie = 'unifises=' + unifises + ';' + 'csrf_token=' + csrf_token + ';';
+            $('#homepage-Unifi-form [name=unifiCookie]').val(cookie);
+            $('#homepage-Unifi-form [name=unifiCookie]').change();
+            messageSingle('', ' Grabbed Cookie - Please Save Now',activeInfo.settings.notifications.position,'#FFF','success','10000');
+        }else{
+            messageSingle('API Connection Failed',response.data,activeInfo.settings.notifications.position,'#FFF','error','10000');
+        }
+        console.log(response);
+    }).fail(function(xhr) {
+        console.error("Organizr Function: API Connection Failed");
+        message('',' Organizr Error',activeInfo.settings.notifications.position,'#FFF','error','10000');
+    });
+}
+function getUnifiSite(service, data = ''){
+    messageSingle('',' Grabbing now...',activeInfo.settings.notifications.position,'#FFF','info','10000');
+    organizrAPI('POST','api/?v1/test/api/connection',{action:service, data:data}).success(function(data) {
+        try {
+            var response = JSON.parse(data);
+        }catch(e) {
+            console.log(e + ' error: ' + data);
+            orgErrorAlert('<h4>' + e + '</h4>' + formatDebug(data));
+            return false;
+        }
+        if(response.data !== false){
+            var sites = '';
+            if(response.data.data){
+                $.each(response.data.data, function(i,v) {
+                    sites += '<div class="form-group row"><div class="col-sm-12"><h4 class="mouse" onclick="unifiSiteApply(\''+v.name+'\')">'+v.desc+'</h4></div></div>';
+                });
+            }else{
+                console.log('no');
+            }
+            var div = `
+                <div class="row">
+                    <div class="col-12">
+                        <div class="card m-b-0">
+                            <div class="form-horizontal">
+                                <div class="card-body">
+                                    <h4 class="card-title" lang="en">Choose Unifi Site</h4>
+                                    `+sites+`
+                                </div>				
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            `;
+            swal({
+                content: createElementFromHTML(div),
+                buttons: false,
+                className: 'bg-org'
+            })
+        }else{
+            messageSingle('API Connection Failed',response.data,activeInfo.settings.notifications.position,'#FFF','error','10000');
+        }
+        console.log(response);
+    }).fail(function(xhr) {
+        console.error("Organizr Function: API Connection Failed");
+        message('',' Organizr Error',activeInfo.settings.notifications.position,'#FFF','error','10000');
+    });
+}
+function unifiSiteApply(name){
+    $('#homepage-Unifi-form [name=unifiSiteName]').val(name);
+    $('#homepage-Unifi-form [name=unifiSiteName]').change();
+    swal.close();
+    messageSingle('', ' Grabbed Site - Please Save Now',activeInfo.settings.notifications.position,'#FFF','success','10000');
+}
 function homepageCalendar(timeout){
 	var timeout = (typeof timeout !== 'undefined') ? timeout : activeInfo.settings.homepage.refresh.calendarRefresh;
     if(activeInfo.settings.homepage.options.alternateHomepageHeaders){