rough in add monitors import wizard
parent
eb48759ff8
commit
c16e101120
|
@ -0,0 +1,209 @@
|
|||
<?php
|
||||
function unparse_url($parsed_url, $substitutions = array() ) {
|
||||
$fields = array('scheme','host','port','user','pass','path','query','fragment');
|
||||
|
||||
foreach ( $fields as $field ) {
|
||||
if ( isset( $substitutions[$field] ) ) {
|
||||
$parsed_url[$field] = $substitutions[$field];
|
||||
}
|
||||
}
|
||||
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
|
||||
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
|
||||
$port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
|
||||
$user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
|
||||
$pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
|
||||
$pass = ($user || $pass) ? "$pass@" : '';
|
||||
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
|
||||
$query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
|
||||
$fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
|
||||
return "$scheme$user$pass$host$port$path$query$fragment";
|
||||
}
|
||||
|
||||
$defaultMonitor = new Monitor();
|
||||
$defaultMonitor->set(array(
|
||||
'StorageId' => 1,
|
||||
'ServerId' => 'auto',
|
||||
'Function' => 'Record',
|
||||
'Type' => 'Ffmpeg',
|
||||
'Enabled' => '1',
|
||||
'Colour' => '4', // 32bit
|
||||
'PreEventCount' => 0,
|
||||
) );
|
||||
|
||||
function probe( &$url_bits ) {
|
||||
global $defaultMonitor;
|
||||
$available_streams = array();
|
||||
if ( ! isset($url_bits['port']) ) {
|
||||
// No port given, do a port scan
|
||||
foreach ( range( 2000, 2007 ) as $port ) {
|
||||
$socket = socket_create( AF_INET, SOCK_STREAM, SOL_TCP );
|
||||
socket_set_option( $socket,
|
||||
SOL_SOCKET, // socket level
|
||||
SO_SNDTIMEO, // timeout option
|
||||
array(
|
||||
"sec"=>0, // Timeout in seconds
|
||||
"usec"=>500 // I assume timeout in microseconds
|
||||
)
|
||||
);
|
||||
$new_stream = null;
|
||||
Info("Testing connection to " . $url_bits['host'].':'.$port);
|
||||
if ( socket_connect( $socket, $url_bits['host'], $port ) ) {
|
||||
$new_stream = $url_bits; // make a copy
|
||||
$new_stream['port'] = $port;
|
||||
} else {
|
||||
socket_close($socket);
|
||||
Info("No connection to ".$url_bits['host'] . " on port $port");
|
||||
continue;
|
||||
}
|
||||
if ( $new_stream ) {
|
||||
if ( ! isset($new_stream['scheme'] ) )
|
||||
$new_stream['scheme'] = 'http';
|
||||
$url = unparse_url($new_stream, array('path'=>'/', 'query'=>'action=snapshot'));
|
||||
list($width, $height, $type, $attr) = getimagesize( $url );
|
||||
Info("Got $width x $height from $url");
|
||||
$new_stream['Width'] = $width;
|
||||
$new_stream['Height'] = $height;
|
||||
|
||||
//try {
|
||||
//if ( $response = do_request( 'GET', $url ) ) {
|
||||
//$new_stream['path'] = '/';
|
||||
//$new_stream['query'] = '?action=stream';
|
||||
//$image = imagecreatefromstring($response);
|
||||
////$size = getimagesize( $image );
|
||||
//
|
||||
//} else {
|
||||
//Info("No response from $url");
|
||||
//}
|
||||
//} catch ( EXception $e ) {
|
||||
//Info("No response from $url");
|
||||
//}
|
||||
$available_streams[] = $new_stream;
|
||||
} // end if new_Stream
|
||||
} // end foreach port to scan
|
||||
} else {
|
||||
// A port was specified, so don't need to port scan.
|
||||
$available_streams[] = $url_bits;
|
||||
}
|
||||
foreach ( $available_streams as &$stream ) {
|
||||
# check for existence in db.
|
||||
$stream['url'] = unparse_url( $stream, array( 'path'=>'/','query'=>'action=stream' ) );
|
||||
$monitors = Monitor::find_all( array( 'Path'=>$stream['url'] ) );
|
||||
if ( count($monitors ) ) {
|
||||
$stream['Monitor'] = $monitors[0];
|
||||
if ( isset( $stream['Width'] ) and ( $stream['Monitor']->Width() != $stream['Width'] ) ) {
|
||||
$stream['Warning'] .= 'Monitor width ('.$stream['Monitor']->Width().') and stream width ('.$stream['Width'].") do not match!\n";
|
||||
}
|
||||
if ( isset( $stream['Height'] ) and ( $stream['Monitor']->Height() != $stream['Height'] ) ) {
|
||||
$stream['Warning'] .= 'Monitor height ('.$stream['Monitor']->Height().') and stream width ('.$stream['Height'].") do not match!\n";
|
||||
}
|
||||
} else {
|
||||
$stream['Monitor'] = $defaultMonitor;
|
||||
if ( isset($stream['Width']) ) {
|
||||
$stream['Monitor']->Width( $stream['Width'] );
|
||||
$stream['Monitor']->Height( $stream['Height'] );
|
||||
}
|
||||
} // Monitor found or not
|
||||
} // end foreach Stream
|
||||
|
||||
#$macCommandString = 'arp ' . $url_bits['host'] . " | awk 'BEGIN{ i=1; } { i++; if(i==3) print $3 }'";
|
||||
#$mac = exec($macCommandString);
|
||||
#Info("Mac $mac");
|
||||
return $available_streams;
|
||||
} // end function probe
|
||||
|
||||
if ( canEdit( 'Monitors' ) ) {
|
||||
switch ( $_REQUEST['action'] ) {
|
||||
case 'probe' :
|
||||
{
|
||||
$available_streams = array();
|
||||
$url_bits = null;
|
||||
if ( preg_match('/(\d+)\.(\d+)\.(\d+)\.(\d+)/', $_REQUEST['url'] ) ) {
|
||||
$url_bits = array( 'host'=>$_REQUEST['url'] );
|
||||
} else {
|
||||
$url_bits = parse_url( $_REQUEST['url'] );
|
||||
}
|
||||
|
||||
if ( 0 ) {
|
||||
// Shortcut test
|
||||
$monitors = Monitor::find_all( array( 'Path'=>$_REQUEST['url'] ) );
|
||||
if ( count( $monitors ) ) {
|
||||
Info("Monitor found for " . $_REQUEST['url']);
|
||||
$url_bits['url'] = $_REQUEST['url'];
|
||||
$url_bits['Monitor'] = $monitors[0];
|
||||
$available_stream[] = $url_bits;
|
||||
ajaxResponse( array ( 'Streams'=>$available_streams) );
|
||||
return;
|
||||
} # end url already has a monitor
|
||||
}
|
||||
|
||||
if ( ! $url_bits ) {
|
||||
ajaxError("The given URL was too malformed to parse.");
|
||||
return;
|
||||
}
|
||||
|
||||
$available_streams = probe( $url_bits );
|
||||
|
||||
ajaxResponse( array('Streams'=>$available_streams) );
|
||||
return;
|
||||
} // end case url_probe
|
||||
case 'import':
|
||||
{
|
||||
|
||||
$file = $_FILES['import_file'];
|
||||
|
||||
if ($file["error"] > 0) {
|
||||
ajaxError($file["error"]);
|
||||
return;
|
||||
} else {
|
||||
$filename = $file["name"];
|
||||
|
||||
$available_streams = array();
|
||||
$row = 1;
|
||||
if (($handle = fopen($file['tmp_name'], 'r')) !== FALSE) {
|
||||
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
|
||||
$name = $data[0];
|
||||
$url = $data[1];
|
||||
$group = $data[2];
|
||||
Info("Have the following line data $name $url $group");
|
||||
|
||||
$url_bits = null;
|
||||
if ( preg_match('/(\d+)\.(\d+)\.(\d+)\.(\d+)/', $url) ) {
|
||||
$url_bits = array( 'host'=>$url, 'scheme'=>'http' );
|
||||
} else {
|
||||
$url_bits = parse_url( $url );
|
||||
}
|
||||
if ( ! $url_bits ) {
|
||||
Info("Bad url, skipping line $name $url $group");
|
||||
continue;
|
||||
}
|
||||
|
||||
$available_streams += probe( $url_bits );
|
||||
|
||||
//$url_bits['url'] = unparse_url( $url_bits );
|
||||
//$url_bits['Monitor'] = $defaultMonitor;
|
||||
//$url_bits['Monitor']->Name( $name );
|
||||
//$url_bits['Monitor']->merge( $_POST['newMonitor'] );
|
||||
//$available_streams[] = $url_bits;
|
||||
|
||||
} // end while rows
|
||||
fclose($handle);
|
||||
ajaxResponse( array('Streams'=>$available_streams) );
|
||||
} else {
|
||||
ajaxError("Uploaded file does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
} // end case import
|
||||
default:
|
||||
{
|
||||
Warning("unknown action " . $_REQUEST['action'] );
|
||||
} // end ddcase default
|
||||
}
|
||||
} else {
|
||||
Warning("Cannot edit monitors" );
|
||||
}
|
||||
|
||||
ajaxError( 'Unrecognised action or insufficient permissions' );
|
||||
|
||||
?>
|
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
//
|
||||
// ZoneMinder web function view file, $Date$, $Revision$
|
||||
// Copyright (C) 2017 ZoneMinder LLC
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canEdit( 'Monitors' ) ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
$focusWindow = true;
|
||||
$navbar = getNavBarHTML();
|
||||
|
||||
xhtmlHeaders(__FILE__, translate('AddMonitors'));
|
||||
?>
|
||||
<body>
|
||||
<div id="page">
|
||||
<?php echo $navbar ?>
|
||||
<div id="content">
|
||||
|
||||
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<div style="position:relative;">
|
||||
<div id="results" style="position: absolute; top:0; right: 0; width: 50%; height: 100%;">
|
||||
<fieldset><legend>Results</legend>
|
||||
<div id="url_results">
|
||||
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div style="width:50%;position: absolute; top:0; left: 0;height: 100%;">
|
||||
<fieldset><legend>Enter by IP or URL</legend>
|
||||
<!--<input type="text" name="newMonitor[Name]" />-->
|
||||
<input type="url" name="newMonitor[Url]" oninput="probe(this);"/>
|
||||
</fieldset>
|
||||
<fieldset><legend>Import CSV Spreadsheet</legend>
|
||||
Spreadsheet should have the following format:<br/>
|
||||
<table class="major">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>URL</th>
|
||||
<th>Group</th>
|
||||
</tr>
|
||||
<tr title="Example Data">
|
||||
<td>Example Name MN1-30 INQ37.01</td>
|
||||
<td>http://10.34.152.20:2001/?action=stream</td>
|
||||
<td>MN1</td>
|
||||
</tr>
|
||||
</table>
|
||||
Defaults to apply to each monitor:<br/>
|
||||
<table><tr><th>Setting</th><th>Value</th></tr>
|
||||
<tr><td><?php echo translate('Function') ?></td><td>
|
||||
<?php
|
||||
$options = array();
|
||||
foreach ( getEnumValues('Monitors', 'Function') as $opt ) {
|
||||
$options[$opt] = translate('Fn'.$opt);
|
||||
}
|
||||
echo htmlSelect( 'newMonitor[Function]', $options, 'Record' );
|
||||
?>
|
||||
</td></tr>
|
||||
<?php
|
||||
$servers = Server::find_all();
|
||||
$ServersById = array();
|
||||
foreach ( $servers as $S ) {
|
||||
$ServersById[$S->Id()] = $S;
|
||||
}
|
||||
|
||||
if ( count($ServersById) > 0 ) { ?>
|
||||
<tr class="Server"><td><?php echo translate('Server')?></td><td>
|
||||
<?php echo htmlSelect( 'newMonitor[ServerId]', array(''=>'Auto')+$ServersById, '' ); ?>
|
||||
</td></tr>
|
||||
<?php
|
||||
}
|
||||
$storage_areas = Storage::find_all();
|
||||
$StorageById = array();
|
||||
foreach ( $storage_areas as $S ) {
|
||||
$StorageById[$S->Id()] = $S;
|
||||
}
|
||||
if ( count($StorageById) > 0 ) {
|
||||
?>
|
||||
<tr class="Storage"><td><?php echo translate('Storage')?></td><td>
|
||||
<?php echo htmlSelect( 'newMonitor[StorageId]', array(''=>'All')+$StorageById, 1 ); ?>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
<input type="file" name="import_file" id="import_file"/>
|
||||
<input type="button" value="Import" onclick="import_csv(this.form);"/>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php xhtmlFooter() ?>
|
|
@ -0,0 +1,89 @@
|
|||
|
||||
var probeReq = new Request.JSON( { url:thisUrl, method: 'get', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getProbeResponse } );
|
||||
|
||||
function probe( url_e ) {
|
||||
probeReq.send( "request=add_monitors&action=probe&url="+url_e.value );
|
||||
}
|
||||
|
||||
var ProbeResults;
|
||||
|
||||
function getProbeResponse( respObj, respText ) {
|
||||
if ( checkStreamForErrors( "getProbeResponse", respObj ) )
|
||||
return;
|
||||
//alert(respText);
|
||||
|
||||
if ( respObj.Streams ) {
|
||||
parseStreams( respObj.Streams );
|
||||
} else {
|
||||
alert("No Streams");
|
||||
}
|
||||
} // end function getProbeResponse
|
||||
|
||||
function parseStreams( Streams ) {
|
||||
ProbeResults = Array();
|
||||
|
||||
var results_div = $j('#url_results')[0];
|
||||
if ( ! results_div ) {
|
||||
console.log("No results div found.");
|
||||
return;
|
||||
}
|
||||
results_div.innerHTML = '';
|
||||
var html = '';
|
||||
|
||||
for( i in Streams ) {
|
||||
var stream = Streams[i];
|
||||
if ( stream.url ) {
|
||||
html += '<p>'+stream.url;
|
||||
if ( stream.Monitor.Id ) {
|
||||
html += ' is already entered into the system by Monitor ' + stream.Monitor.Id + ' ' + stream.Monitor.Name + '<br/>';
|
||||
html += '<input type="button" value="Edit" onclick="addMonitor(\''+stream.url+'\');"/>';
|
||||
} else {
|
||||
html += '<input type="button" value="Add" onclick="addMonitor(\''+stream.url+'\');"/>';
|
||||
}
|
||||
html += '</p>';
|
||||
ProbeResults[stream.url] = stream;
|
||||
} else {
|
||||
//console.log(stream);
|
||||
}
|
||||
} // end for eah Stream
|
||||
|
||||
results_div.innerHTML = html;
|
||||
}
|
||||
|
||||
function addMonitor(url) {
|
||||
if ( ! ProbeResults[url] ) {
|
||||
alert("Monitor for url " + url + " not found in probe results." );
|
||||
return;
|
||||
}
|
||||
var Stream = ProbeResults[url];
|
||||
var Monitor = Stream.Monitor;
|
||||
|
||||
popup_url = '?view=monitor&newMonitor[Path]='+url;
|
||||
keys = Object.keys( Monitor );
|
||||
for ( i in Monitor ) {
|
||||
if ( ! Monitor[i] )
|
||||
continue;
|
||||
if ( Monitor[i] == 'null' )
|
||||
Monitor[i]='';
|
||||
popup_url += '&newMonitor['+i+']='+Monitor[i];
|
||||
}
|
||||
createPopup( popup_url, 'zmMonitor0', 'monitor' );
|
||||
}
|
||||
|
||||
function import_csv( form ) {
|
||||
var formData = new FormData( form );
|
||||
console.log(formData);
|
||||
//formData.append('file', $('#file')[0].files[0]);
|
||||
|
||||
$j.ajax({
|
||||
url : thisUrl+"?request=add_monitors&action=import",
|
||||
type : 'POST',
|
||||
data : formData,
|
||||
processData: false, // tell jQuery not to process the data
|
||||
contentType: false, // tell jQuery not to set contentType
|
||||
success : function(data) {
|
||||
var json = JSON.parse(data);
|
||||
parseStreams( json.Streams );
|
||||
}
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue