ncp-web: implement dashboard

This commit is contained in:
nachoparker 2018-04-03 13:08:20 +02:00
parent b94bcb4213
commit fa1ec759f5
10 changed files with 282 additions and 82 deletions

13
bin/ncp-diag Executable file → Normal file
View File

@ -32,10 +32,12 @@ echo "datadir|$DATADIR$DIRINFO"
echo "data disk usage|$( df -h "$DATADIR" | tail -1 | awk '{ print $3"/"$2 }')"
}
echo "rootfs usage|$( df -h / | tail -1 | awk '{ print $3"/"$2 }')"
echo "swapfile|$( swapon | tail -1 | awk '{ print $1 }' )"
SWP="$( swapon | tail -1 | awk '{ print $1 }' )"
[[ "$SWP" == "" ]] && SWP="none"
echo "swapfile|$SWP"
# Nextcloud
VERSION="$( sudo -u www-data php /var/www/nextcloud/occ status | grep "version:" | awk '{ print $3 }' )"
VERSION="$( php /var/www/nextcloud/occ status | grep "version:" | awk '{ print $3 }' )"
if [[ "$VERSION" != "" ]]; then
echo "Nextcloud check|ok"
echo "Nextcloud version|$VERSION"
@ -75,13 +77,10 @@ echo "gateway|$GW"
echo "interface|$IFACE"
# Certificates
LEOUT="$( /etc/letsencrypt/letsencrypt-auto certificates 2>/dev/null )"
CERTS="$( echo -e "$LEOUT" | grep "Domains:" | awk '{ print $2 }' | tr '\n' ' ' )"
CDUE="$( echo -e "$LEOUT" | grep "VALID:" | grep -oP "\d+ days" | tr '\n' ' ' )"
CERTS="$( grep "SSLCertificateFile /etc/letsencrypt/live/" /etc/apache2/sites-available/nextcloud.conf \
| sed 's|.*SSLCertificateFile /etc/letsencrypt/live/||;s|/fullchain.pem||' )"
[[ "$CERTS" == "" ]] && CERTS=none
[[ "$CDUE" == "" ]] && CDUE=none
echo "certificates|$CERTS"
echo "certs due|$CDUE"
RESOLV="$( ping -c 1 "$CERTS" 2>/dev/null | head -1 | grep -oP '\d{1,3}(.\d{1,3}){3}' )"
echo "NAT loopback|$( [[ "$RESOLV" == "$IP" ]] && echo yes || echo no )"

View File

@ -39,7 +39,7 @@ echo "<--! Paste this in GitHub report -->"
##
open_summary "NextCloudPi diagnostics"
ncp-diag | column -t -s'|'
bash /usr/local/bin/ncp-diag | column -t -s'|'
close_summary
##

38
bin/ncp-suggestions Normal file
View File

@ -0,0 +1,38 @@
#!/bin/bash
#
# NextCloudPi configuration suggestions
#
# Copyleft 2018 by Ignacio Nunez Hernanz <nacho _a_t_ ownyourbits _d_o_t_ com>
# GPL licensed (see end of file) * Use at your own risk!
#
# Usage:
# sudo ncp-suggestions "$( ncp-diag )"
#
# More at https://ownyourbits.com
#
OUT="$@"
DNSMASQ_ON="$( grep "^ACTIVE_=" /usr/local/etc/nextcloudpi-config.d/dnsmasq.sh | cut -d'=' -f2 )"
grep -q "distribution|.*bian GNU/Linux 9" <<<"$OUT" || \
echo -e "You are using an unsupported distro release. Please upgrade to latest Debian/Raspbian"
[[ $DNSMASQ_ON != "yes" ]] && \
grep -q "NAT loopback|no" <<<"$OUT" && \
echo -e "\nYou should enable dnsmasq to use your domain inside home"
grep -q "certificates|none" <<<"$OUT" && \
echo -e "\nYou should run Lets Encrypt for trusted encrypted access"
grep -q "port check .*|closed" <<<"$OUT" && \
echo -e "\nYou should open your ports for Lets Encrypt and external access"
grep -q "USB devices|none" <<<"$OUT" || {
grep -q "data in SD|yes" <<<"$OUT" && \
echo -e "\nYou should use nc-datadir to move your files to your plugged in USB drive"
grep -q "automount|no" <<<"$OUT" && \
echo -e "\nYou should enable automount to use your plugged in USB drive"
}

View File

@ -1,7 +1,11 @@
[v0.53.8](https://github.com/nextcloud/nextcloudpi/commit/cc733af) (2018-04-02) ncp-web: fix update notification
[v0.53.10](https://github.com/nextcloud/nextcloudpi/commit/dce58cc) (2018-04-03) ncp-web: implement dashboard
[v0.53.7](https://github.com/nextcloud/nextcloudpi/commit/d4ca26a) (2018-03-29) ncp-web: use random passwords for NC and ncp-web
[v0.53.9](https://github.com/nextcloud/nextcloudpi/commit/486d6ef) (2018-04-02) SSH: stop service upon activation
[v0.53.8 ](https://github.com/nextcloud/nextcloudpi/commit/afd2c8e) (2018-04-02) ncp-web: fix update notification
[v0.53.7 ](https://github.com/nextcloud/nextcloudpi/commit/d4ca26a) (2018-03-29) ncp-web: use random passwords for NC and ncp-web
[v0.53.6 ](https://github.com/nextcloud/nextcloudpi/commit/151160b) (2018-03-27) samba: dont force NAME_REGEX for username

View File

@ -7,7 +7,7 @@
#
# Usage:
#
# ./installer.sh nc-diag.sh <IP> (<img>)
# ./installer.sh nc-info.sh <IP> (<img>)
#
# See installer.sh instructions for details
# More at: https://ownyourbits.com
@ -17,36 +17,16 @@ DESCRIPTION="Print NextCloudPi system info"
configure()
{
# info
local OUT="$( ncp-diag )"
echo "Gathering information..."
local OUT="$( bash /usr/local/bin/ncp-diag )"
# info
echo "$OUT" | column -t -s'|'
# suggestions
DNSMASQ_ON="$( grep "^ACTIVE_=" /usr/local/etc/nextcloudpi-config.d/dnsmasq.sh | cut -d'=' -f2 )"
grep -q "distribution|.*bian GNU/Linux 9" <<<"$OUT" || \
echo -e "\nYou are using an unsupported distro release. Please upgrade to latest Debian/Raspbian"
[[ $DNSMASQ_ON != "yes" ]] && \
grep -q "NAT loopback|no" <<<"$OUT" && \
echo -e "\nYou should enable dnsmasq to use your domain inside home"
grep -q "certificates|none" <<<"$OUT" && \
echo -e "\nYou should run Lets Encrypt for trusted encrypted access"
grep -q "port check .*|closed" <<<"$OUT" && \
echo -e "\nYou should open your ports for Lets Encrypt and external access"
grep -q "USB devices|none" <<<"$OUT" || {
grep -q "data in SD|yes" <<<"$OUT" && \
echo -e "\nYou should use nc-datadir to move your files to your plugged in USB drive"
grep -q "automount|no" <<<"$OUT" && \
echo -e "\nYou should enable automount to uyyse your plugged in USB drive"
}
echo
bash /usr/local/bin/ncp-suggestions "$OUT"
return 0
}
@ -68,4 +48,3 @@ install() { :; }
# along with this script; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
# Boston, MA 02111-1307 USA

65
ncp-web/img/dashboard.svg Normal file
View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="11.858879"
width="12.743636"
version="1.0"
viewBox="0 0 12.743636 11.858879"
id="svg6"
sodipodi:docname="app-dark.svg"
inkscape:version="0.92.2 2405546, 2018-03-11">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="740"
inkscape:window-height="480"
id="namedview8"
showgrid="false"
inkscape:zoom="7.375"
inkscape:cx="14.032185"
inkscape:cy="11.980041"
inkscape:window-x="534"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg6" />
<rect
ry="1.9665999"
height="31.997"
width="31.997"
display="none"
y="-16.117743"
x="-1.967815"
id="rect2"
style="display:none;fill:#cccccc" />
<path
d="m 0.9210639,6.4191634 h 2.171293 L 5.0996871,2.3379828 7.7014791,9.71018 9.6253517,6.4209341 11.822572,6.4190841"
stroke-miterlimit="100"
id="path4"
style="fill:#ffffff;stroke:#ffffff;stroke-width:1.81625974;stroke-linecap:round;stroke-miterlimit:100;stroke-opacity:1"
inkscape:connector-curvature="0" />
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -111,6 +111,11 @@ HTML;
</a>
</div>
<div id="header-right">
<div id="dashboard-btn">
<div id="expand">
<div class="icon-dashboard"></div>
</div>
</div>
<?php
if ( file_exists( 'wizard' ) )
echo <<<HTML
@ -139,7 +144,7 @@ HTML;
<?php
// fill options with contents from directory
$files = array_diff(scandir($modules_path), array('.', '..', 'nc-wifi.sh', 'l10n'));
$files = array_diff(scandir($modules_path), array('.', '..', 'nc-wifi.sh', 'nc-info.sh', 'l10n'));
foreach ($files as $file) {
$script = pathinfo($file, PATHINFO_FILENAME);
@ -169,24 +174,33 @@ HTML;
<div id="app-content">
<div id="app-navigation-toggle" class="icon-menu hidden"></div>
<h2 id="config-box-title"><?php echo $l->__("Configure NextCloudPi features"); ?></h2>
<a href="#" target="_blank">
<div id="config-extra-info" class="icon-info"></div>
</a>
<div id="config-box-info"></div>
<br/>
<div id="config-box-wrapper" class="hidden">
<form>
<div id="config-box"></div>
<div id="config-button-wrapper">
<button id="config-button"><?php echo $l->__("Run"); ?></button>
<img id="loading-gif" src="img/loading-small.gif">
<div id="circle-retstatus" class="icon-red-circle"></div>
</div>
</form>
<textarea readonly id="details-box" rows="12"></textarea>
<div id="config-wrapper" class="hidden">
<h2 id="config-box-title" class="text-title"><?php echo $l->__("System Info"); ?></h2>
<div id="config-box-info-txt"></div>
<a href="#" target="_blank">
<div id="config-extra-info" class="icon-info"></div>
</a>
<br/>
<div id="config-box-wrapper" class="table-wrapper">
<form>
<div id="config-box"></div>
<div id="config-button-wrapper">
<button id="config-button"><?php echo $l->__("Run"); ?></button>
<img id="loading-gif" src="img/loading-small.gif">
<div id="circle-retstatus" class="icon-red-circle"></div>
</div>
</form>
<textarea readonly id="details-box" class="outputbox" rows="12"></textarea>
</div>
</div>
<div id="dashboard-wrapper">
<h2 class="text-title"><?php echo $l->__("System Info"); ?></h2>
<div id="dashboard-suggestions" class="table-wrapper"></div>
<div id="dashboard-table" class="outputbox table-wrapper"></div>
</div>
<div id="loading-info-gif"> <img src="img/loading-small.gif"> </div>
</div>
<div id="poweroff-dialog" class='dialog primary hidden'>
@ -200,7 +214,8 @@ HTML;
<?php
include('csrf.php');
echo '<input type="hidden" id="csrf-token" name="csrf-token" value="' . getCSRFToken() . '"/>';
echo '<input type="hidden" id="csrf-token" name="csrf-token" value="' . getCSRFToken() . '"/>';
echo '<input type="hidden" id="csrf-token-dash" name="csrf-token-dash" value="' . getCSRFToken() . '"/>';
?>
<script src="minified.js"></script>
<script src="ncp.js"></script>

View File

@ -38,8 +38,7 @@ if ( $_POST['action'] == "cfgreq" )
$fh = fopen( $path . $_POST['ref'] . '.sh' ,'r')
or exit( '{ "output": "' . $file . ' read error" }' );
// Get new token
echo '{ "token": "' . getCSRFToken() . '",';
echo '{ "token": "' . getCSRFToken() . '",'; // Get new token
echo ' "output": ';
$output = "<table>";
@ -52,10 +51,10 @@ if ( $_POST['action'] == "cfgreq" )
$checked = "";
if ( $matches[2] == "yes" )
$checked = "checked";
$output = $output . "<tr>";
$output = $output . "<td><label for=\"$matches[1]\">". $l->__($matches[1], $_POST['ref']) ."</label></td>";
$output = $output . "<td><input type=\"checkbox\" id=\"$matches[1]\" name=\"$matches[1]\" value=\"$matches[2]\" $checked></td>";
$output = $output . "</tr>";
$output .= "<tr>";
$output .= "<td><label for=\"$matches[1]\">". $l->__($matches[1], $_POST['ref']) ."</label></td>";
$output .= "<td><input type=\"checkbox\" id=\"$matches[1]\" name=\"$matches[1]\" value=\"$matches[2]\" $checked></td>";
$output .= "</tr>";
}
// drop down menu
else if(preg_match('/^(\w+)_=\[(([_\w]+,)*[_\w]+)\]$/', $line, $matches))
@ -78,14 +77,14 @@ if ( $_POST['action'] == "cfgreq" )
// text field
else if ( preg_match('/^(\w+)_=(.*)$/', $line, $matches) )
{
$output = $output . "<tr>";
$output = $output . "<td><label for=\"$matches[1]\">". $l->__($matches[1], $_POST['ref']) ."</label></td>";
$output = $output . "<td><input type=\"text\" name=\"$matches[1]\" id=\"$matches[1]\" value=\"$matches[2]\" size=\"40\"></td>";
$output = $output . "</tr>";
$output .= "<tr>";
$output .= "<td><label for=\"$matches[1]\">". $l->__($matches[1], $_POST['ref']) ."</label></td>";
$output .= "<td><input type=\"text\" name=\"$matches[1]\" id=\"$matches[1]\" value=\"$matches[2]\" size=\"40\"></td>";
$output .= "</tr>";
}
}
$output = $output . "</table>";
$output .= "</table>";
fclose($fh);
echo json_encode( $output ) . ' }'; // close JSON
@ -129,9 +128,8 @@ else if ( $_POST['action'] == "launch" && $_POST['config'] )
file_put_contents($file, $code )
or exit( '{ "output": "' . $file . ' write error" }' );
// Get new token
echo '{ "token": "' . getCSRFToken() . '",';
echo ' "ref": "' . $_POST['ref'] . '",';
echo '{ "token": "' . getCSRFToken() . '",'; // Get new token
echo ' "ref": "' . $_POST['ref'] . '",';
echo ' "output": "" , ';
echo ' "ret": ';
@ -154,6 +152,49 @@ else
{
shell_exec('bash -c "( sleep 2 && sudo reboot ) 2>/dev/null >/dev/null &"');
}
else if ( $_POST['action'] == "info" )
{
exec( 'bash /usr/local/bin/ncp-diag', $output, $ret );
// info table
$table = '<table id="dashtable">';
foreach( $output as $line )
{
$table .= "<tr>";
$fields = explode( "|", $line );
$table .= "<td>$fields[0]</td>";
$class = "";
if ( strpos( $fields[1], "up" ) !== false
|| strpos( $fields[1], "ok" ) !== false
|| strpos( $fields[1], "open" ) !== false )
$class = 'class="ok-field"';
if ( strpos( $fields[1], "down" ) !== false
|| strpos( $fields[1], "error" ) !== false )
$class = 'class="error-field"';
$table .= "<td $class>$fields[1]</td>";
$table .= "</tr>";
}
$table .= "</table>";
// suggestions
$suggestions = "";
if ( $ret == 0 )
{
exec( "bash /usr/local/bin/ncp-suggestions \"" . implode( "\n", $output ) . '"', $out, $ret );
foreach( $out as $line )
if ( $line != "" )
$suggestions .= "<p class=\"warn-field\">‣ $line</p>";
}
// return JSON
echo '{ "token": "' . getCSRFToken() . '",'; // Get new token
echo ' "ref": " ' . $_POST['ref'] . '",';
echo ' "table": ' . json_encode( $table ) . ' , ';
echo ' "suggestions": ' . json_encode( $suggestions ) . ' , ';
echo ' "ret": "' . $ret . '" }';
}
}
// License

View File

@ -1049,22 +1049,22 @@ select {
border-style:solid
}
#config-box-wrapper {
.table-wrapper {
width: 80%;
max-width: 450px;
margin-left: auto;
margin-right: auto;
}
#config-box-wrapper table {
.table-wrapper table {
width: 100%;
}
#config-box-wrapper input[type='text'] {
.table-wrapper input[type='text'] {
width: 100%;
}
#details-box {
.outputbox {
width: 100%;
}
@ -1072,11 +1072,18 @@ select {
display: none;
}
#config-box-title {
#loading-info-gif {
display: flex;
justify-content: center;
align-items: center;
margin-top: 96px;
}
.text-title {
text-align: center;
}
#config-box-info {
#config-box-info-txt {
white-space: pre-wrap;
text-align: center;
}
@ -1126,6 +1133,9 @@ select {
.icon-reboot-white {
background-image: url('img/reboot.svg');
}
.icon-dashboard {
background-image: url('img/dashboard.svg');
}
.icon-wizard-white {
background-image: url('img/wizard.svg');
@ -1259,3 +1269,28 @@ a#versionlink:hover {
height: 100%;
z-index: 2500;
}
.ok-field{
color: green;
}
.error-field{
color: red;
}
.warn-field{
color: gray;
}
#dashtable tr {
height: 25px;
border-bottom: 1px solid #ebebeb;
}
#dashtable td {
border-bottom: 1px solid #ebebeb;
}
#dashboard-suggestions {
margin-bottom: 1em;
}

View File

@ -22,10 +22,14 @@ function cfgreqReceive( result )
var ret = $.parseJSON( result );
if ( ret.token )
$('#csrf-token').set( { value: ret.token } );
$('#details-box' ).hide();
$('#dashboard-wrapper').hide();
$('#circle-retstatus').hide();
$('#config-box').ht( ret.output );
$('#config-box-title').fill( $( '#' + selectedID + '-desc' ).get( '.value' ) );
$('#config-box-info' ).fill( $( '#' + selectedID + '-info' ).get( '.value' ) );
$('#config-box-title' ).fill( $( '#' + selectedID + '-desc' ).get( '.value' ) );
$('#config-box-info-txt' ).fill( $( '#' + selectedID + '-info' ).get( '.value' ) );
$('#config-wrapper').show();
$('#config-box-wrapper').show();
$('#config-extra-info').set( { $display: 'inline-block' } );
$('#config-extra-info').up().set( '@href', 'https://github.com/nextcloud/nextcloudpi/wiki/Configuration-Reference#' + selectedID );
@ -81,9 +85,6 @@ $(function()
confLock = false;
}).error( errorMsg );
//clear details box
$('#details-box').hide( '' );
});
// Launch selected script
@ -300,7 +301,30 @@ $(function()
// click to nextcloud button
$('#nextcloudpi').set( '@href', window.location.protocol + '//' + window.location.hostname );
});
// load dashboard info
$.request('post', 'ncp-launcher.php', { action: 'info',
csrf_token: $( '#csrf-token-dash' ).get( '.value' ) }).then(
function success( result )
{
var ret = $.parseJSON( result );
if ( ret.token )
$('#csrf-token').set( { value: ret.token } );
$('#loading-info-gif').hide();
$('#dashboard-table').ht( ret.table );
$('#dashboard-suggestions').ht( ret.suggestions );
} ).error( errorMsg );
// dashboard button
$( '#dashboard-btn' ).on('click', function(e)
{
$( '#config-wrapper' ).hide();
$( '#dashboard-wrapper' ).show();
$( '#' + selectedID ).set('-active');
selectedID = null;
} );
} );
// License
//