Browse Source

Added SpeedTest

causefx 8 years ago
parent
commit
f4416e9c42

+ 1 - 1
api/functions/homepage-functions.php

@@ -1552,7 +1552,7 @@ function buildHomepageSettings(){
 				break;
 		}
 		$homepageList .= '
-		<div class="col-md-3 sort-homepage m-t-10">
+		<div class="col-md-3 sort-homepage m-t-10 hvr-grow">
 			<div class="homepage-drag fc-event '.$class.' lazyload"  data-src="'.$image.'">
 				<span class="ordinal-position text-uppercase badge bg-org homepage-number" data-link="'.$key.'" style="float:left;width: 30px;">'.$val.'</span>
 				<span class="homepage-text">&nbsp; '.strtoupper(substr($key, 13)).'</span>

+ 19 - 0
api/plugins/api/speedTest.php

@@ -0,0 +1,19 @@
+<?php
+if(isset($_POST['data']['plugin'])){
+    switch ($_POST['data']['plugin']) {
+        case 'SpeedTest/settings/get':
+            if(qualifyRequest(1)){
+                $result['status'] = 'success';
+                $result['statusText'] = 'success';
+                $result['data'] = speedTestGetSettings();
+            }else{
+                $result['status'] = 'error';
+                $result['statusText'] = 'API/Token invalid or not set';
+                $result['data'] = null;
+            }
+            break;
+        default:
+            //DO NOTHING!!
+            break;
+    }
+}

+ 6 - 0
api/plugins/config/speedTest.php

@@ -0,0 +1,6 @@
+<?php
+return array(
+    'SPEEDTEST-enabled' => false,
+    'SPEEDTEST-Auth-include' => '1',
+	'SPEEDTEST-option2-include' => '',
+);

+ 194 - 0
api/plugins/js/speedTest.js

@@ -0,0 +1,194 @@
+/* PHP MAILER JS FILE */
+/*
+$(document).on('click', '#PHPMAILER-settings-button', function() {
+	var post = {
+        plugin:'PHPMailer/settings/get', // used for switch case in your API call
+        api:'api/?v1/plugin', // API Endpoint will always be this for custom plugin API calls
+        name:$(this).attr('data-plugin-name'),
+        configName:$(this).attr('data-config-name'),
+        messageTitle:'', // Send succees message title (top line)
+        messageBody:'Disabled '+$(this).attr('data-plugin-name'), // Send succees message body (bottom line)
+        error:'Organizr Function: API Connection Failed' // conole error message
+    };
+	var callbacks = $.Callbacks(); // init callbacks var
+    //callbacks.add(  ); // add function to callback to be fired after API call
+    //settingsAPI(post,callbacks); // exec API call
+    //ajaxloader(".content-wrap","in");
+    //setTimeout(function(){ buildPlugins();ajaxloader(); }, 3000);
+});
+*/
+function clamp(num, min, max) {
+  return num <= min ? min : num >= max ? max : num;
+}
+function I(id){return document.getElementById(id);}
+var w=null; //speedtest worker
+function startStop(){
+	if(w!=null){
+		//speedtest is running, abort
+		w.postMessage('abort');
+		w=null;
+		$('#speedTestButtonText').text('Start');
+		initUI();
+	}else{
+		//test is not running, begin
+		w=new Worker('api/plugins/misc/speedTest/speedtest_worker.min.js');
+		w.postMessage('start'); //Add optional parameters as a JSON object to this command
+		$('#speedTestButtonText').text('Running');
+		w.onmessage=function(e){
+			var data=e.data.split(';');
+			var status=Number(data[0]);
+			if(status>=4){
+				//test completed
+				$('#speedTestButtonText').text('Re-Test');
+				w=null;
+			}
+			var downloadText = Math.ceil((data[1]/1000)*1000);
+			var downloadPercent = clamp(Math.ceil(((data[1]/1000)*100)/5)*5, 0,100);
+			var uploadText = Math.ceil((data[2]/1000)*1000);
+			var uploadPercent = clamp(Math.ceil(((data[2]/1000)*100)/5)*5, 0,100);
+			I("ip").textContent=data[4];
+			I("dlText").textContent=(status==1&&data[1]==0)?"...":Math.ceil(data[1]);
+			I("ulText").textContent=(status==3&&data[2]==0)?"...":Math.ceil(data[2]);
+			I("pingText").textContent=Math.ceil(data[3]);
+			I("jitText").textContent=Math.ceil(data[5]);
+			var prog=(Number(data[6])*2+Number(data[7])*2+Number(data[8]))/5;
+			I("progress").style.width=(100*prog)+"%";
+			$('#downloadPercent').attr('class', 'css-bar css-bar-'+downloadPercent+' css-bar-lg css-bar-default').attr('data-label', downloadText+'Mbps');
+			$('#uploadPercent').attr('class', 'css-bar css-bar-'+uploadPercent+' css-bar-lg css-bar-warning pull-right').attr('data-label', uploadText+'Mbps');
+		};
+	}
+}
+//poll the status from the worker every 200ms (this will also update the UI)
+setInterval(function(){
+	if(w) w.postMessage('status');
+},200);
+//function to (re)initialize UI
+function initUI(){
+	I("dlText").textContent="";
+	I("ulText").textContent="";
+	I("pingText").textContent="";
+	I("jitText").textContent="";
+	I("ip").textContent="";
+	I("progress").style.width="";
+	$('#downloadPercent').attr('class', 'css-bar css-bar-0 css-bar-lg css-bar-default').attr('data-label', '0Mbps');
+	$('#uploadPercent').attr('class', 'css-bar css-bar-0 css-bar-lg css-bar-warning pull-right').attr('data-label', '0Mbps');
+}
+// FUNCTIONS
+speedTestLaunch()
+function speedTestLaunch(){
+    if(typeof activeInfo == 'undefined'){
+        setTimeout(function () {
+            speedTestLaunch();
+        }, 1000);
+    }else{
+        if(activeInfo.plugins["SPEEDTEST-enabled"] == true){
+            if (activeInfo.user.groupID <= activeInfo.plugins.includes["SPEEDTEST-Auth-include"]) {
+                var menuList = `<li><a class="inline-popups speedTestModal" href="#speedtest-area" data-effect="mfp-zoom-out"><i class="fa fa-rocket fa-fw"></i> <span lang="en">Test Internet Speed</span></a></li>`;
+				var htmlDOM = `
+		    	<div id="speedtest-area" class="white-popup mfp-with-anim mfp-hide">
+		    		<div class="col-md-4 col-md-offset-4">
+						<div class="panel bg-org panel-info">
+							<div class="panel-heading">
+								<span lang="en">Test Speed to Server</span>
+								<button id="startStopBtn" onclick="startStop()" class="btn btn-info waves-effect waves-light pull-right"><span lang="en" id="speedTestButtonText">Start</span> <i class="fa fa-rocket m-l-5"></i></button>
+							</div>
+							<div class="panel-body">
+								<div id="test">
+									<div class="row hidden-xs">
+										<div class="col-md-6 col-xs-6"><div id="downloadPercent" data-label="0Mbps" style="font-size: 15px;"></div></div>
+										<div class="col-md-6 col-xs-6"><div id="uploadPercent" data-label="0Mbps" style="font-size: 15px;"></div></div>
+									</div>
+									<div class="progress progress-sm">
+										<div id="progress" class="progress-bar progress-bar-info active progress-bar-striped" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
+											<span class="sr-only">0% Complete (success)</span>
+										</div>
+									</div>
+				                    <div class="white-box m-b-0">
+				                        <div class="user-btm-box">
+				                            <div class="col-md-3 col-xs-6 p-l-0 p-r-0 text-center">
+				                                <p class="text-success"><i class="ti-download fa-2x"></i></p>
+				                                <h1 id="dlText"></h1>
+												<h4 class="">Mbps</h4>
+											</div>
+				                            <div class="col-md-3 col-xs-6 p-l-0 p-r-0 text-center">
+				                                <p class="text-warning"><i class="ti-upload fa-2x"></i></p>
+				                                <h1 id="ulText"></h1>
+												<h4 class="">Mbps</h4>
+											</div>
+				                            <div class="col-md-3 col-xs-6 p-l-0 p-r-0 text-center">
+				                                <p class="text-purple"><i class="ti-direction-alt fa-2x"></i></p>
+				                                <h1 id="pingText"></h1>
+												<h4 class="">ms</h4>
+											</div>
+				                            <div class="col-md-3 col-xs-6 p-l-0 p-r-0 text-center">
+				                                <p class="text-info"><i class="ti-pulse fa-2x"></i></p>
+				                                <h1 id="jitText"></h1>
+												<h4 class="">ms</h4>
+											</div>
+				                        </div>
+				                    </div>
+								</div>
+								<script type="text/javascript">initUI();</script>
+							</div>
+							<div class="panel-footer"> IP Address: <span id="ip"></span> </div>
+						</div>
+		    		</div>
+		    	</div>
+		    	`;
+				$('.append-menu').after(menuList);
+	            $('.organizr-area').after(htmlDOM);
+	            pageLoad();
+			}
+        }
+    }
+}
+
+// CHANGE CUSTOMIZE Options
+$(document).on('change asColorPicker::close', '#SPEEDTEST-settings-page :input', function(e) {
+    var input = $(this);
+    switch ($(this).attr('type')) {
+        case 'switch':
+        case 'checkbox':
+            var value = $(this).prop("checked") ? true : false;
+            break;
+        default:
+            var value = $(this).val().toString();
+    }
+	var post = {
+        api:'api/?v1/update/config',
+        name:$(this).attr("name"),
+        type:$(this).attr("data-type"),
+        value:value,
+        messageTitle:'',
+        messageBody:'Updated Value for '+$(this).parent().parent().find('label').text(),
+        error:'Organizr Function: API Connection Failed'
+    };
+	var callbacks = $.Callbacks();
+    //callbacks.add( buildCustomizeAppearance );
+    settingsAPI(post,callbacks);
+    //disable button then renable
+    $('#SPEEDTEST-settings-page :input').prop('disabled', 'true');
+    setTimeout(
+        function(){
+            $('#SPEEDTEST-settings-page :input').prop('disabled', null);
+            input.emulateTab();
+        },
+        2000
+    );
+
+});
+$(document).on('click', '#SPEEDTEST-settings-button', function() {
+    var post = {
+        plugin:'SpeedTest/settings/get', // used for switch case in your API call
+    };
+    ajaxloader(".content-wrap","in");
+    organizrAPI('POST','api/?v1/plugin',post).success(function(data) {
+        var response = JSON.parse(data);
+        $('#SPEEDTEST-settings-items').html(buildFormGroup(response.data));
+        $(".select2").select2();
+        $('.selectpicker').selectpicker();
+    }).fail(function(xhr) {
+        console.error("Organizr Function: API Connection Failed");
+    });
+    ajaxloader();
+});

+ 7 - 0
api/plugins/misc/speedTest/empty.php

@@ -0,0 +1,7 @@
+<?php
+header( "HTTP/1.1 200 OK" );
+header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
+header("Cache-Control: post-check=0, pre-check=0", false);
+header("Pragma: no-cache");
+header("Connection: keep-alive");
+?>

+ 27 - 0
api/plugins/misc/speedTest/garbage.php

@@ -0,0 +1,27 @@
+<?php
+// Disable Compression
+@ini_set('zlib.output_compression', 'Off');
+@ini_set('output_buffering', 'Off');
+@ini_set('output_handler', '');
+// Headers
+header('HTTP/1.1 200 OK');
+// Download follows...
+header('Content-Description: File Transfer');
+header('Content-Type: application/octet-stream');
+header('Content-Disposition: attachment; filename=random.dat');
+header('Content-Transfer-Encoding: binary');
+// Never cache me
+header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
+header('Cache-Control: post-check=0, pre-check=0', false);
+header('Pragma: no-cache');
+// Generate data
+$data=openssl_random_pseudo_bytes(1048576);
+// Deliver chunks of 1048576 bytes
+$chunks=isset($_GET['ckSize']) ? intval($_GET['ckSize']) : 4;
+if(empty($chunks)){$chunks = 4;}
+if($chunks>100){$chunks = 100;}
+for($i=0;$i<$chunks;$i++){
+    echo $data;
+    flush();
+}
+?>

+ 99 - 0
api/plugins/misc/speedTest/getIP.php

@@ -0,0 +1,99 @@
+<?php
+
+$ip = "";
+header('Content-Type: text/plain; charset=utf-8');
+if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
+    $ip = $_SERVER['HTTP_CLIENT_IP'];
+} elseif (!empty($_SERVER['X-Real-IP'])) {
+    $ip = $_SERVER['X-Real-IP'];
+} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
+    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
+} else {
+    $ip = $_SERVER['REMOTE_ADDR'];
+}
+
+$ip = preg_replace("/^::ffff:/", "", $ip);
+
+if (strpos($ip, '::1') !== false) {
+    echo $ip . " - localhost ipv6 access";
+    die();
+}
+if (strpos($ip, '127.0.0') !== false) {
+    echo $ip . " - localhost ipv4 access";
+    die();
+}
+
+/**
+ * Optimized algorithm from http://www.codexworld.com
+ *
+ * @param float $latitudeFrom
+ * @param float $longitudeFrom
+ * @param float $latitudeTo
+ * @param float $longitudeTo
+ *
+ * @return float [km]
+ */
+function distance($latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo) {
+    $rad = M_PI / 180;
+    $theta = $longitudeFrom - $longitudeTo;
+    $dist = sin($latitudeFrom * $rad) * sin($latitudeTo * $rad) + cos($latitudeFrom * $rad) * cos($latitudeTo * $rad) * cos($theta * $rad);
+    return acos($dist) / $rad * 60 * 1.853;
+}
+
+if (isset($_GET["isp"])) {
+    $isp = "";
+    $ip = (strpos($ip, ',') !== false) ? explode(', ',$ip)[1] : $ip;
+    try {
+        $json = @file_get_contents("https://ipinfo.io/" . $ip . "/json");
+        $details = json_decode($json, true);
+        if (is_array($details) || is_object($details)){
+            if (array_key_exists("org", $details))
+                $isp .= $details["org"];
+            else
+                $isp .= "Unknown ISP";
+            if (array_key_exists("country", $details))
+                $isp .= ", " . $details["country"];
+            $clientLoc = NULL;
+            $serverLoc = NULL;
+            if (array_key_exists("loc", $details))
+                $clientLoc = $details["loc"];
+            if (isset($_GET["distance"])) {
+                if ($clientLoc) {
+                    $json = file_get_contents("https://ipinfo.io/json");
+                    $details = json_decode($json, true);
+                    if (array_key_exists("loc", $details))
+                        $serverLoc = $details["loc"];
+                    if ($serverLoc) {
+                        try {
+                            $clientLoc = explode(",", $clientLoc);
+                            $serverLoc = explode(",", $serverLoc);
+                            $dist = distance($clientLoc[0], $clientLoc[1], $serverLoc[0], $serverLoc[1]);
+                            if ($_GET["distance"] == "mi") {
+                                $dist /= 1.609344;
+                                $dist = round($dist, -1);
+                                if ($dist < 15)
+                                    $dist = "<15";
+                                $isp .= " (" . $dist . " mi)";
+                            }else if ($_GET["distance"] == "km") {
+                                $dist = round($dist, -1);
+                                if ($dist < 20)
+                                    $dist = "<20";
+                                $isp .= " (" . $dist . " km)";
+                            }
+                        } catch (Exception $e) {
+
+                        }
+                    }
+                }
+            }
+        }else{
+            $isp = "Unknown ISP";
+        }
+    } catch (Exception $ex) {
+        $isp = "Unknown ISP";
+    }
+    echo $ip . " - " . $isp;
+} else {
+    echo $ip;
+}
+?>

File diff suppressed because it is too large
+ 0 - 0
api/plugins/misc/speedTest/speedtest_worker.min.js


+ 73 - 0
api/plugins/misc/speedTest/telemetry.php

@@ -0,0 +1,73 @@
+<?php
+include_once('telemetry_settings.php');
+
+$ip=($_SERVER['REMOTE_ADDR']);
+$ua=($_SERVER['HTTP_USER_AGENT']);
+$lang=""; if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) $lang=($_SERVER['HTTP_ACCEPT_LANGUAGE']);
+$dl=($_POST["dl"]);
+$ul=($_POST["ul"]);
+$ping=($_POST["ping"]);
+$jitter=($_POST["jitter"]);
+$log=($_POST["log"]);
+
+if($db_type=="mysql"){
+    $conn = new mysqli($MySql_hostname, $MySql_username, $MySql_password, $MySql_databasename) or die("1");
+    $stmt = $conn->prepare("INSERT INTO speedtest_users (ip,ua,lang,dl,ul,ping,jitter,log) VALUES (?,?,?,?,?,?,?,?)") or die("2");
+    $stmt->bind_param("ssssssss",$ip,$ua,$lang,$dl,$ul,$ping,$jitter,$log) or die("3");
+    $stmt->execute() or die("4");
+    $stmt->close() or die("5");
+    $conn->close() or die("6");
+
+}elseif($db_type=="sqlite"){
+    $conn = new PDO("sqlite:$Sqlite_db_file") or die("1");
+    $conn->exec("
+        CREATE TABLE IF NOT EXISTS `speedtest_users` (
+        `id`    INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+        `timestamp`     timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+        `ip`    text NOT NULL,
+        `ua`    text NOT NULL,
+        `lang`  text NOT NULL,
+        `dl`    text,
+        `ul`    text,
+        `ping`  text,
+        `jitter`        text,
+        `log`   longtext
+        );
+    ");
+    $stmt = $conn->prepare("INSERT INTO speedtest_users (ip,ua,lang,dl,ul,ping,jitter,log) VALUES (?,?,?,?,?,?,?,?)") or die("2");
+    $stmt->execute(array($ip,$ua,$lang,$dl,$ul,$ping,$jitter,$log)) or die("3");
+    $conn = null;
+}elseif($db_type=="postgresql"){
+    // Prepare connection parameters for db connection
+    $conn_host = "host=$PostgreSql_hostname";
+    $conn_db = "dbname=$PostgreSql_databasename";
+    $conn_user = "user=$PostgreSql_username";
+    $conn_password = "password=$PostgreSql_password";
+    // Create db connection
+    $conn = new PDO("pgsql:$conn_host;$conn_db;$conn_user;$conn_password") or die("1");
+    $stmt = $conn->prepare("INSERT INTO speedtest_users (ip,ua,lang,dl,ul,ping,jitter,log) VALUES (?,?,?,?,?,?,?,?)") or die("2");
+    $stmt->execute(array($ip,$ua,$lang,$dl,$ul,$ping,$jitter,$log)) or die("3");
+    $conn = null;
+}
+elseif($db_type=="csv"){
+    // Prepare the csv formatted string
+    date_default_timezone_set($timezone);
+    $date = date('Y-m-d H:i:s');
+    $str = '"' . $date . '",';
+    $str .= '"' . $ip . '",';
+    $str .= '"' . $ua . '",';
+    $str .= '"' . $dl . '",';
+    $str .= '"' . $ul . '",';
+    $str .= '"' . $ping . '",';
+    $str .= '"' . $jitter . '"' . "\n";
+
+    // Set header if this is a new file
+    if (!file_exists($Csv_File)) {
+        $header = '"date","ip","ua","download","upload","ping","jitter"' . "\n";
+        file_put_contents($Csv_File, $header, FILE_APPEND);
+    }
+
+    // Writting line to file
+    file_put_contents($Csv_File, $str, FILE_APPEND);
+}
+?>

+ 24 - 0
api/plugins/misc/speedTest/telemetry_settings.php

@@ -0,0 +1,24 @@
+<?php
+
+$db_type="mysql"; //Type of db: "mysql", "sqlite" or "postgresql" or "csv"
+
+// Sqlite3 settings
+$Sqlite_db_file = "../telemetry.sql";
+
+// Mysql settings
+$MySql_username="USERNAME";
+$MySql_password="PASSWORD";
+$MySql_hostname="DB_HOSTNAME";
+$MySql_databasename="DB_NAME";
+
+// Postgresql settings
+$PostgreSql_username="USERNAME";
+$PostgreSql_password="PASSWORD";
+$PostgreSql_hostname="DB_HOSTNAME";
+$PostgreSql_databasename="DB_NAME";
+
+// CSV settings
+$Csv_File="reports.csv";
+$timezone='UTC';
+
+?>

+ 36 - 0
api/plugins/speedTest.php

@@ -0,0 +1,36 @@
+<?php
+
+// PLUGIN INFORMATION
+$GLOBALS['plugins'][]['SpeedTest'] = array( // Plugin Name
+    'name'=>'SpeedTest', // Plugin Name
+	'author'=>'CauseFX', // Who wrote the plugin
+    'category'=>'Utilities', // One to Two Word Description
+    'link'=>'https://github.com/PHPMailer/PHPMailer', // Link to plugin info
+    //'fileName'=>'php-mailer.php',
+	//'configFile'=>'php-mailer.php',
+	//'apiFile'=>'php-mailer.php',
+	'idPrefix'=>'SPEEDTEST', // html element id prefix
+	'configPrefix'=>'SPEEDTEST', // config file prefix for array items without the hypen
+    'version'=>'1.0.0', // SemVer of plugin
+    'image'=>'plugins/images/speedtest.png', // 1:1 non transparent image for plugin
+	'settings'=>true, // does plugin need a settings page? true or false
+    'homepage'=>false // Is plugin for use on homepage? true or false
+);
+// INCLUDE/REQUIRE FILES
+
+// PLUGIN FUNCTIONS
+
+/* GET PHPMAILER SETTINGS */
+function speedTestGetSettings(){
+	return array(
+		'Options' => array(
+			array(
+				'type' => 'select',
+				'name' => 'SPEEDTEST-Auth-include',
+				'label' => 'Minimum Authentication',
+				'value' => $GLOBALS['SPEEDTEST-Auth-include'],
+				'options' => groupSelect()
+			)
+		)
+	);
+}

+ 1 - 0
index.php

@@ -29,6 +29,7 @@
 	<link href="plugins/bower_components/multiselect/css/multi-select.css" rel="stylesheet" type="text/css" />
 	<link href="plugins/bower_components/owl.carousel/owl.carousel.min.css" rel="stylesheet" type="text/css" />
 	<link href="plugins/bower_components/owl.carousel/owl.theme.default.css" rel="stylesheet" type="text/css" />
+	<link href="plugins/bower_components/hover/hover-min.css" rel="stylesheet" type="text/css" />
 	<link id="style" href="css/dark.css?v=<?php echo $GLOBALS['installedVersion']; ?>" rel="stylesheet">
 	<link href="css/organizr.css?v=<?php echo $GLOBALS['installedVersion']; ?>" rel="stylesheet">
 	<?php echo pluginFiles('css'); ?>

File diff suppressed because it is too large
+ 8 - 0
plugins/bower_components/hover/hover-min.css


BIN
plugins/images/speedtest.png


Some files were not shown because too many files changed in this diff