Merge branch 'storageareas' into zma_to_thread
This commit is contained in:
commit
834dfbfe0c
|
@ -2,3 +2,6 @@
|
|||
path = web/api/app/Plugin/Crud
|
||||
url = https://github.com/FriendsOfCake/crud.git
|
||||
branch = 3.0
|
||||
[submodule "web/api/app/Plugin/CakePHP-Enum-Behavior"]
|
||||
path = web/api/app/Plugin/CakePHP-Enum-Behavior
|
||||
url = https://github.com/asper/CakePHP-Enum-Behavior.git
|
||||
|
|
|
@ -213,7 +213,8 @@ CREATE TABLE `Events` (
|
|||
KEY `MonitorId` (`MonitorId`),
|
||||
KEY `StartTime` (`StartTime`),
|
||||
KEY `Frames` (`Frames`),
|
||||
KEY `Archived` (`Archived`)
|
||||
KEY `Archived` (`Archived`),
|
||||
KEY `EndTime_DiskSpace` (`EndTime`,`DiskSpace`)
|
||||
) ENGINE=@ZM_MYSQL_ENGINE@;
|
||||
|
||||
--
|
||||
|
@ -277,7 +278,7 @@ CREATE TABLE `Groups` (
|
|||
--Table structure for table `Groups_Monitors`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `Groups_Monitors`
|
||||
DROP TABLE IF EXISTS `Groups_Monitors`;
|
||||
CREATE TABLE `Groups_Monitors` (
|
||||
`Id` INT(10) unsigned NOT NULL auto_increment,
|
||||
`GroupId` int(10) unsigned NOT NULL,
|
||||
|
@ -640,6 +641,7 @@ CREATE TABLE `Storage` (
|
|||
`Type` enum('local','s3fs') NOT NULL default 'local',
|
||||
`DiskSpace` bigint unsigned default NULL,
|
||||
`Scheme enum('Deep','Medium','Shallow') NOT NULL default 'Medium',
|
||||
`ServerId` int(10) unsigned,
|
||||
PRIMARY KEY (`Id`)
|
||||
) ENGINE=@ZM_MYSQL_ENGINE@;
|
||||
|
||||
|
@ -668,7 +670,25 @@ insert into Users VALUES (NULL,'admin',password('admin'),'',1,'View','Edit','Edi
|
|||
--
|
||||
-- Add a sample filter to purge the oldest 100 events when the disk is 95% full
|
||||
--
|
||||
insert into Filters values (NULL,'PurgeWhenFull','{"sort_field":"Id","terms":[{"val":0,"attr":"Archived","op":"="},{"cnj":"and","val":95,"attr":"DiskPercent","op":">="}],"limit":100,"sort_asc":1}',0,0,0,0,0,0,'',1,0,1,0);
|
||||
`Id` int(10) unsigned NOT NULL auto_increment,
|
||||
`Name` varchar(64) NOT NULL default '',
|
||||
`Query` text NOT NULL,
|
||||
`AutoArchive` tinyint(3) unsigned NOT NULL default '0',
|
||||
`AutoVideo` tinyint(3) unsigned NOT NULL default '0',
|
||||
`AutoUpload` tinyint(3) unsigned NOT NULL default '0',
|
||||
`AutoEmail` tinyint(3) unsigned NOT NULL default '0',
|
||||
`AutoMessage` tinyint(3) unsigned NOT NULL default '0',
|
||||
`AutoExecute` tinyint(3) unsigned NOT NULL default '0',
|
||||
`AutoExecuteCmd` tinytext,
|
||||
`AutoDelete` tinyint(3) unsigned NOT NULL default '0',
|
||||
`AutoMove` tinyint(3) unsigned NOT NULL default '0',
|
||||
`AutoMoveTo` smallint(5) unsigned NOT NULL default 0,
|
||||
`UpdateDiskSpace` tinyint(3) unsigned NOT NULL default '0',
|
||||
`Background` tinyint(1) unsigned NOT NULL default '0',
|
||||
`Concurrent` tinyint(1) unsigned NOT NULL default '0',
|
||||
|
||||
insert into Filters values (NULL,'PurgeWhenFull','{"sort_field":"Id","terms":[{"val":0,"attr":"Archived","op":"="},{"cnj":"and","val":95,"attr":"DiskPercent","op":">="}],"limit":100,"sort_asc":1}',0/*AutoArchive*/,0/*AutoVideo*/,0/*AutoUpload*/,0/*AutoEmail*/,0/*AutoMessage*/,0/*AutoExecute*/,'',1/*AutoDelete*/,0/*AutoMove*/,0/*MoveTo*/,0/*UpdateDiskSpace*/,1/*Background*/,0/*Concurrent*/);
|
||||
insert into Filters values (NULL,'Update DiskSpace','{"terms":[{"attr":"DiskSpace","op":"IS","val":"NULL"}]}',0,0,0,0,0,0,'',0,0,0,1,1,0);
|
||||
|
||||
--
|
||||
-- Add in some sample control protocol definitions
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||
AND table_name = 'Storage'
|
||||
AND column_name = 'ServerId'
|
||||
) > 0,
|
||||
"SELECT 'Column ServerId already exists in Storage'",
|
||||
"ALTER TABLE Storage ADD `ServerId` int(10) unsigned AFTER `Scheme`"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
||||
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*) FROM Filters WHERE Name = 'Update DiskSpace'
|
||||
AND Query = '{"terms":[{"attr":"DiskSpace","op":"IS","val":"NULL"}]}'
|
||||
) > 0,
|
||||
"SELECT 'Update Disk Space Filter already exists.'",
|
||||
"INSERT INTO Filters (Name,Query,UpdateDiskSpace,Background) values ('Update DiskSpace','{\"terms\":[{\"attr\":\"DiskSpace\",\"op\":\"IS\",\"val\":\"NULL\"}]}',1,1)"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
|
@ -154,11 +154,21 @@ sub Path {
|
|||
|
||||
if ( ! $$event{Path} ) {
|
||||
my $Storage = $event->Storage();
|
||||
$$event{Path} = join('/', $Storage->Path(), $event->RelativePath() );
|
||||
}
|
||||
return $$event{Path};
|
||||
}
|
||||
|
||||
sub RelativePath {
|
||||
my $event = shift;
|
||||
if ( @_ ) {
|
||||
$$event{RelativePath} = $_[0];
|
||||
}
|
||||
|
||||
if ( ! $$event{RelativePath} ) {
|
||||
if ( $$event{Scheme} eq 'Deep' ) {
|
||||
if ( $event->Time() ) {
|
||||
$$event{Path} = join('/',
|
||||
$Storage->Path(),
|
||||
$$event{RelativePath} = join('/',
|
||||
$event->{MonitorId},
|
||||
strftime( '%y/%m/%d/%H/%M/%S',
|
||||
localtime($event->Time())
|
||||
|
@ -166,30 +176,28 @@ sub Path {
|
|||
);
|
||||
} else {
|
||||
Error("Event $$event{Id} has no value for Time(), unable to determine path");
|
||||
$$event{Path} = '';
|
||||
$$event{RelativePath} = '';
|
||||
}
|
||||
} elsif ( $$event{Scheme} eq 'Medium' ) {
|
||||
if ( $event->Time() ) {
|
||||
$$event{Path} = join('/',
|
||||
$Storage->Path(),
|
||||
$$event{RelativePath} = join('/',
|
||||
$event->{MonitorId},
|
||||
strftime( '%Y-%m-%d', localtime($event->Time())),
|
||||
$event->{Id},
|
||||
);
|
||||
} else {
|
||||
Error("Event $$event{Id} has no value for Time(), unable to determine path");
|
||||
$$event{Path} = '';
|
||||
$$event{RelativePath} = '';
|
||||
}
|
||||
} else { # Shallow
|
||||
$$event{Path} = join('/',
|
||||
$Storage->Path(),
|
||||
$$event{RelativePath} = join('/',
|
||||
$event->{MonitorId},
|
||||
$event->{Id},
|
||||
);
|
||||
} # end if Scheme
|
||||
} # end if ! Path
|
||||
|
||||
return $$event{Path};
|
||||
return $$event{RelativePath};
|
||||
}
|
||||
|
||||
sub GenerateVideo {
|
||||
|
@ -337,7 +345,7 @@ sub delete_files {
|
|||
return;
|
||||
}
|
||||
Debug("Deleting files for Event $$event{Id} from $storage_path.");
|
||||
my $link_path = $$event{MonitorId}."/*/*/*/.".$$event{Id};
|
||||
my $link_path = $$event{MonitorId}.'/*/*/*/.'.$$event{Id};
|
||||
#Debug( "LP1:$link_path" );
|
||||
my @links = glob($link_path);
|
||||
#Debug( "L:".$links[0].": $!" );
|
||||
|
@ -371,7 +379,7 @@ sub delete_files {
|
|||
}
|
||||
} # end if links
|
||||
} else {
|
||||
my $command = "/bin/rm -rf ". $event->Path();
|
||||
my $command = '/bin/rm -rf '. $storage_path . '/'. $event->RelativePath();
|
||||
ZoneMinder::General::executeShellCommand( $command );
|
||||
}
|
||||
} # end sub delete_files
|
||||
|
|
|
@ -238,8 +238,13 @@ MAIN: while( $loop ) {
|
|||
} elsif ( $$Storage{Scheme} eq 'Medium' ) {
|
||||
foreach my $event_dir ( glob("$monitor_dir/*/*") ) {
|
||||
next if ! -d $event_dir;
|
||||
my $Event = $fs_events->{$event} = new ZoneMinder::Event();
|
||||
$$Event{Id} = $event;
|
||||
my ( $date, $event_id ) = $event_dir =~ /^$monitor_dir\/(\d{4}\-\d{2}\-\d{2})\/(\d\+)$/;
|
||||
if ( ! $event_id ) {
|
||||
Debug("Unable to parse date/event_id from $event_dir");
|
||||
next;
|
||||
}
|
||||
my $Event = $fs_events->{$event_id} = new ZoneMinder::Event();
|
||||
$$Event{Id} = $event_id;
|
||||
$$Event{Path} = $event_dir;
|
||||
$Event->MonitorId( $monitor_dir );
|
||||
$Event->StorageId( $Storage->Id() );
|
||||
|
|
|
@ -70,6 +70,7 @@ Cache::config('default', array('engine' => 'Apc'));
|
|||
*
|
||||
*/
|
||||
CakePlugin::load('Crud');
|
||||
CakePlugin::load('CakePHP-Enum-Behavior');
|
||||
|
||||
/**
|
||||
* You can attach event listeners to the request lifecycle as Dispatcher Filter. By default CakePHP bundles two filters:
|
||||
|
@ -142,6 +143,27 @@ foreach( $configvals as $key => $value) {
|
|||
Configure::write( $key, $value );
|
||||
}
|
||||
|
||||
// For Human-readability, use ZM_SERVER_HOST or ZM_SERVER_NAME in zm.conf, and convert it here to a ZM_SERVER_ID
|
||||
if ( ! defined('ZM_SERVER_ID') ) {
|
||||
App::uses('ClassRegistry', 'Utility');
|
||||
$ServerModel = ClassRegistry::init('Server');
|
||||
if ( defined('ZM_SERVER_NAME') and ZM_SERVER_NAME ) {
|
||||
$Server = $ServerModel->find( 'first', array( 'conditions'=>array('Name'=>ZM_SERVER_NAME) ) );
|
||||
if ( ! $Server ) {
|
||||
Error('Invalid Multi-Server configration detected. ZM_SERVER_NAME set to ' . ZM_SERVER_NAME . ' in zm.conf, but no corresponding entry found in Servers table.');
|
||||
} else {
|
||||
define( 'ZM_SERVER_ID', $Server['Server']['Id'] );
|
||||
}
|
||||
} else if ( defined('ZM_SERVER_HOST') and ZM_SERVER_HOST ) {
|
||||
$Server = $ServerModel->find( 'first', array( 'conditions'=>array('Name'=>ZM_SERVER_HOST) ) );
|
||||
if ( ! $Server ) {
|
||||
Error('Invalid Multi-Server configration detected. ZM_SERVER_HOST set to ' . ZM_SERVER_HOST . ' in zm.conf, but no corresponding entry found in Servers table.');
|
||||
} else {
|
||||
define( 'ZM_SERVER_ID', $Server['Server']['Id'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function process_configfile($configFile) {
|
||||
if ( is_readable( $configFile ) ) {
|
||||
$configvals = array();
|
||||
|
|
|
@ -15,6 +15,9 @@ class MonitorsController extends AppController {
|
|||
*/
|
||||
public $components = array('Paginator', 'RequestHandler');
|
||||
|
||||
public function beforeRender() {
|
||||
$this->set($this->Monitor->enumValues());
|
||||
}
|
||||
public function beforeFilter() {
|
||||
parent::beforeFilter();
|
||||
$canView = $this->Session->Read('monitorPermission');
|
||||
|
@ -111,8 +114,7 @@ class MonitorsController extends AppController {
|
|||
public function add() {
|
||||
if ( $this->request->is('post') ) {
|
||||
|
||||
if ($this->Session->Read('systemPermission') != 'Edit')
|
||||
{
|
||||
if ( $this->Session->Read('systemPermission') != 'Edit' ) {
|
||||
throw new UnauthorizedException(__('Insufficient privileges'));
|
||||
return;
|
||||
}
|
||||
|
@ -120,8 +122,15 @@ class MonitorsController extends AppController {
|
|||
$this->Monitor->create();
|
||||
if ($this->Monitor->save($this->request->data)) {
|
||||
$this->daemonControl($this->Monitor->id, 'start');
|
||||
return $this->flash(__('The monitor has been saved.'), array('action' => 'index'));
|
||||
//return $this->flash(__('The monitor has been saved.'), array('action' => 'index'));
|
||||
$message = 'Saved';
|
||||
} else {
|
||||
$message = 'Error';
|
||||
}
|
||||
$this->set(array(
|
||||
'message' => $message,
|
||||
'_serialize' => array('message')
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,8 +147,7 @@ class MonitorsController extends AppController {
|
|||
if (!$this->Monitor->exists($id)) {
|
||||
throw new NotFoundException(__('Invalid monitor'));
|
||||
}
|
||||
if ($this->Session->Read('monitorPermission') != 'Edit')
|
||||
{
|
||||
if ($this->Session->Read('monitorPermission') != 'Edit') {
|
||||
throw new UnauthorizedException(__('Insufficient privileges'));
|
||||
return;
|
||||
}
|
||||
|
@ -160,12 +168,11 @@ class MonitorsController extends AppController {
|
|||
'conditions' => array('Id' => $id)
|
||||
))['Monitor']['Function'];
|
||||
// We don't pass the request data as the monitor object because it may be a subset of the full monitor array
|
||||
if ( $func == 'None' ) {
|
||||
$this->daemonControl( $this->Monitor->id, 'stop' );
|
||||
} else {
|
||||
$this->daemonControl( $this->Monitor->id, 'restart' );
|
||||
}
|
||||
if ( ( $func != 'None' ) and ( $this->Monitor->ServerId == ZM_SERVER_ID ) ) {
|
||||
$this->daemonControl( $this->Monitor->id, 'start' );
|
||||
}
|
||||
} // end function edit
|
||||
|
||||
/**
|
||||
* delete method
|
||||
|
@ -179,8 +186,7 @@ class MonitorsController extends AppController {
|
|||
if (!$this->Monitor->exists()) {
|
||||
throw new NotFoundException(__('Invalid monitor'));
|
||||
}
|
||||
if ($this->Session->Read('systemPermission') != 'Edit')
|
||||
{
|
||||
if ($this->Session->Read('systemPermission') != 'Edit') {
|
||||
throw new UnauthorizedException(__('Insufficient privileges'));
|
||||
return;
|
||||
}
|
||||
|
@ -213,32 +219,29 @@ class MonitorsController extends AppController {
|
|||
// expected format: http(s):/portal-api-url/monitors/alarm/id:M/command:C.json
|
||||
// where M=monitorId
|
||||
// where C=on|off|status
|
||||
public function alarm()
|
||||
{
|
||||
public function alarm() {
|
||||
$id = $this->request->params['named']['id'];
|
||||
$cmd = strtolower($this->request->params['named']['command']);
|
||||
if (!$this->Monitor->exists($id)) {
|
||||
throw new NotFoundException(__('Invalid monitor'));
|
||||
}
|
||||
if ( $cmd != 'on' && $cmd != 'off' && $cmd != 'status')
|
||||
{
|
||||
if ( $cmd != 'on' && $cmd != 'off' && $cmd != 'status' ) {
|
||||
throw new BadRequestException(__('Invalid command'));
|
||||
}
|
||||
$zm_path_bin = Configure::read('ZM_PATH_BIN');
|
||||
|
||||
switch ($cmd)
|
||||
{
|
||||
case "on":
|
||||
switch ($cmd) {
|
||||
case 'on':
|
||||
$q = '-a';
|
||||
$verbose = "-v";
|
||||
$verbose = '-v';
|
||||
break;
|
||||
case "off":
|
||||
$q = "-c";
|
||||
$verbose = "-v";
|
||||
case 'off':
|
||||
$q = '-c';
|
||||
$verbose = '-v';
|
||||
break;
|
||||
case "status":
|
||||
$verbose = ""; // zmu has a bug - gives incorrect verbose output in this case
|
||||
$q = "-s";
|
||||
case 'status':
|
||||
$verbose = ''; // zmu has a bug - gives incorrect verbose output in this case
|
||||
$q = '-s';
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -253,11 +256,9 @@ class MonitorsController extends AppController {
|
|||
$config = $this->Config->find('first', $options);
|
||||
$zmAuthRelay = $config['Config']['Value'];
|
||||
|
||||
$auth="";
|
||||
if ($zmOptAuth)
|
||||
{
|
||||
if ($zmAuthRelay == 'hashed')
|
||||
{
|
||||
$auth='';
|
||||
if ( $zmOptAuth ) {
|
||||
if ( $zmAuthRelay == 'hashed' ) {
|
||||
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_HASH_SECRET'));
|
||||
$config = $this->Config->find('first', $options);
|
||||
$zmAuthHashSecret = $config['Config']['Value'];
|
||||
|
@ -265,16 +266,12 @@ class MonitorsController extends AppController {
|
|||
$time = localtime();
|
||||
$ak = $zmAuthHashSecret.$this->Session->Read('username').$this->Session->Read('passwordHash').$time[2].$time[3].$time[4].$time[5];
|
||||
$ak = md5($ak);
|
||||
$auth = " -A ".$ak;
|
||||
}
|
||||
elseif ($zmAuthRelay == 'plain')
|
||||
{
|
||||
$auth = " -U " .$this->Session->Read('username')." -P ".$this->Session->Read('password');
|
||||
$auth = ' -A '.$ak;
|
||||
} else if ( $zmAuthRelay == 'plain' ) {
|
||||
$auth = ' -U ' .$this->Session->Read('username').' -P '.$this->Session->Read('password');
|
||||
|
||||
}
|
||||
elseif ($zmAuthRelay == 'none')
|
||||
{
|
||||
$auth = " -U " .$this->Session->Read('username');
|
||||
} else if ( $zmAuthRelay == 'none' ) {
|
||||
$auth = ' -U ' .$this->Session->Read('username');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,8 +282,6 @@ class MonitorsController extends AppController {
|
|||
'status' => $status,
|
||||
'_serialize' => array('status'),
|
||||
));
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Check if a daemon is running for the monitor id
|
||||
|
@ -308,9 +303,9 @@ class MonitorsController extends AppController {
|
|||
|
||||
// Pass -d for local, otherwise -m
|
||||
if ($monitor[0]['Type'] == 'Local') {
|
||||
$args = "-d ". $monitor[0]['Device'];
|
||||
$args = '-d '. $monitor[0]['Device'];
|
||||
} else {
|
||||
$args = "-m ". $monitor[0]['Id'];
|
||||
$args = '-m '. $monitor[0]['Id'];
|
||||
}
|
||||
|
||||
// Build the command, and execute it
|
||||
|
@ -346,9 +341,9 @@ class MonitorsController extends AppController {
|
|||
}
|
||||
|
||||
if ($monitor['Type'] == 'Local') {
|
||||
$args = "-d " . $monitor['Device'];
|
||||
$args = '-d ' . $monitor['Device'];
|
||||
} else {
|
||||
$args = "-m " . $id;
|
||||
$args = '-m ' . $id;
|
||||
}
|
||||
|
||||
if ($monitor['Function'] == 'Monitor') {
|
||||
|
@ -365,5 +360,4 @@ class MonitorsController extends AppController {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // end class MonitorsController
|
||||
|
|
|
@ -86,10 +86,10 @@ class Monitor extends AppModel {
|
|||
);
|
||||
|
||||
/**
|
||||
* * hasMany associations
|
||||
* *
|
||||
* * @var array
|
||||
* */
|
||||
* hasMany associations
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $hasAndBelongsToMany = array(
|
||||
'Group' => array(
|
||||
'className' => 'Group',
|
||||
|
@ -108,5 +108,16 @@ class Monitor extends AppModel {
|
|||
'counterQuery' => ''
|
||||
),
|
||||
);
|
||||
public $actsAs = array(
|
||||
'CakePHP-Enum-Behavior.Enum' => array(
|
||||
'Type' => array('Local','Remote','File','Ffmpeg','Libvlc','cURL'),
|
||||
'Function' => array('None','Monitor','Modect','Record','Mocord','Nodect'),
|
||||
'Orientation' => array('0','90','180','270','hori','vert'),
|
||||
'OutputCodec' => array('h264','mjpeg','mpeg1','mpeg2'),
|
||||
'OutputContainer' => array('auto','mp4','mkv'),
|
||||
'DefaultView' => array('Events','Control'),
|
||||
'Status' => array('Unknown','NotRunning','Running','NoSignal','Signal'),
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 7108489f218c54d36d235d3af91d6da2f8311237
|
|
@ -0,0 +1,2 @@
|
|||
echo json_encode($message);
|
||||
echo json_encode($monitor);
|
|
@ -0,0 +1,2 @@
|
|||
$xml = Xml::fromArray(array('response' => $message));
|
||||
echo $xml->asXML();
|
|
@ -160,7 +160,16 @@ class Event {
|
|||
|
||||
public function getStreamSrc( $args=array(), $querySep='&' ) {
|
||||
if ( $this->{'DefaultVideo'} and $args['mode'] != 'jpeg' ) {
|
||||
return ( ZM_BASE_PATH != '/' ? ZM_BASE_PATH : '' ).'/index.php?view=view_video&eid='.$this->{'Id'};
|
||||
$streamSrc = ZM_BASE_PROTOCOL.'://';
|
||||
$Monitor = $this->Monitor();
|
||||
if ( $Monitor->ServerId() ) {
|
||||
$Server = $Monitor->Server();
|
||||
$streamSrc .= $Server->Hostname();
|
||||
} else {
|
||||
$streamSrc .= $_SERVER['HTTP_HOST'];
|
||||
}
|
||||
$streamSrc .= ( ZM_BASE_PATH != '/' ? ZM_BASE_PATH : '' ).'/index.php?view=view_video&eid='.$this->{'Id'};
|
||||
return $streamSrc;
|
||||
}
|
||||
|
||||
$streamSrc = ZM_BASE_URL.ZM_PATH_ZMS;
|
||||
|
|
|
@ -295,8 +295,8 @@ private $control_fields = array(
|
|||
}
|
||||
return $filters;
|
||||
}
|
||||
public function save( $new_values = null ) {
|
||||
|
||||
public function save( $new_values = null ) {
|
||||
|
||||
if ( $new_values ) {
|
||||
foreach ( $new_values as $k=>$v ) {
|
||||
|
@ -304,8 +304,10 @@ private $control_fields = array(
|
|||
}
|
||||
}
|
||||
|
||||
$sql = 'UPDATE Monitors SET '.implode(', ', array_map( function($field) {return $field.'=?';}, array_keys( $this->defaults ) ) ) . ' WHERE Id=?';
|
||||
$values = array_map( function($field){return $this->{$field};}, $this->fields );
|
||||
$fields = array_keys( $this->defaults );
|
||||
|
||||
$sql = 'UPDATE Monitors SET '.implode(', ', array_map( function($field) {return $field.'=?';}, $fields ) ) . ' WHERE Id=?';
|
||||
$values = array_map( function($field){return $this->{$field};}, $fields );
|
||||
$values[] = $this->{'Id'};
|
||||
dbQuery( $sql, $values );
|
||||
} // end function save
|
||||
|
|
|
@ -70,15 +70,38 @@ class Storage {
|
|||
Warning( "Unknown function call Storage->$fn from $file:$line" );
|
||||
}
|
||||
}
|
||||
public static function find_all() {
|
||||
$storage_areas = array();
|
||||
$result = dbQuery( 'SELECT * FROM Storage ORDER BY Name');
|
||||
public static function find_all( $parameters = null, $options = null ) {
|
||||
$filters = array();
|
||||
$sql = 'SELECT * FROM Storage ';
|
||||
$values = array();
|
||||
|
||||
if ( $parameters ) {
|
||||
$fields = array();
|
||||
$sql .= 'WHERE ';
|
||||
foreach ( $parameters as $field => $value ) {
|
||||
if ( $value == null ) {
|
||||
$fields[] = $field.' IS NULL';
|
||||
} else if ( is_array( $value ) ) {
|
||||
$func = function(){return '?';};
|
||||
$fields[] = $field.' IN ('.implode(',', array_map( $func, $value ) ). ')';
|
||||
$values += $value;
|
||||
|
||||
} else {
|
||||
$fields[] = $field.'=?';
|
||||
$values[] = $value;
|
||||
}
|
||||
}
|
||||
$sql .= implode(' AND ', $fields );
|
||||
}
|
||||
if ( $options and isset($options['order']) ) {
|
||||
$sql .= ' ORDER BY ' . $options['order'];
|
||||
}
|
||||
$result = dbQuery($sql, $values);
|
||||
$results = $result->fetchALL(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Storage');
|
||||
foreach ( $results as $row => $obj ) {
|
||||
$storage_areas[] = $obj;
|
||||
$storage_cache[$obj->Id()] = $obj;
|
||||
$filters[] = $obj;
|
||||
}
|
||||
return $storage_areas;
|
||||
return $filters;
|
||||
}
|
||||
public function disk_usage_percent() {
|
||||
$path = $this->Path();
|
||||
|
@ -95,11 +118,8 @@ class Storage {
|
|||
Error("disk_total_space returned false for " . $path );
|
||||
return 0;
|
||||
}
|
||||
$free = disk_free_space( $path );
|
||||
if ( ! $free ) {
|
||||
Error("disk_free_space returned false for " . $path );
|
||||
}
|
||||
$usage = round(($total - $free) / $total * 100);
|
||||
$used = $this->disk_used_space();
|
||||
$usage = round( ($used / $total) * 100);
|
||||
return $usage;
|
||||
}
|
||||
public function disk_total_space() {
|
||||
|
|
|
@ -1280,6 +1280,7 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) {
|
|||
$filter['sql'] .= ' not regexp '.$value;
|
||||
break;
|
||||
case '=[]' :
|
||||
case 'IN' :
|
||||
$filter['sql'] .= ' in ('.join( ',', $valueList ).')';
|
||||
break;
|
||||
case '![]' :
|
||||
|
|
|
@ -320,6 +320,9 @@ if ($reload == 'reload') ob_start();
|
|||
}
|
||||
$func = function($S){ return '<span title="'.human_filesize($S->disk_used_space()) . ' of ' . human_filesize($S->disk_total_space()).'">'.$S->Name() . ': ' . $S->disk_usage_percent().'%' . '</span>'; };
|
||||
#$func = function($S){ return '<span title="">'.$S->Name() . ': ' . $S->disk_usage_percent().'%' . '</span>'; };
|
||||
if ( count($storage_areas) >= 4 )
|
||||
$storage_areas = Storage::find_all( array('ServerId'=>null) );
|
||||
if ( count($storage_areas) < 4 )
|
||||
echo implode( ', ', array_map ( $func, $storage_areas ) );
|
||||
echo ' ' . ZM_PATH_MAP .': '. getDiskPercent(ZM_PATH_MAP).'%';
|
||||
?></li>
|
||||
|
|
|
@ -37,7 +37,7 @@ $eventCounts = array(
|
|||
'filter' => array(
|
||||
'Query' => array(
|
||||
'terms' => array(
|
||||
array( 'attr' => 'DateTime', 'op' => '>=', 'val' => '-1 hour' ),
|
||||
array( 'attr' => 'StartDateTime', 'op' => '>=', 'val' => '-1 hour' ),
|
||||
)
|
||||
)
|
||||
),
|
||||
|
|
|
@ -55,7 +55,17 @@ function SetImageSource( monId, time ) {
|
|||
if ( eMonId[i] == monId && time >= eStartSecs[i] && time <= eEndSecs[i] ) {
|
||||
var duration = eEndSecs[i]-eStartSecs[i];
|
||||
var frame = parseInt((time - eStartSecs[i])/(duration)*eventFrames[i])+1;
|
||||
console.log("SetImageSource: " + time + " duration: " + duration + " frame: " + frame );
|
||||
var storage = Storage[eStorageId[i]];
|
||||
if ( storage.ServerId ) {
|
||||
var server = Servers[storage.ServerId];
|
||||
if ( server ) {
|
||||
console.log( server.Hostname + " for event " + eId[i] );
|
||||
return location.protocol + '//' + server.Hostname + '/index.php?view=image&eid=' + eId[i] + '&fid='+frame + "&width=" + monitorCanvasObj[monId].width + "&height=" + monitorCanvasObj[monId].height;
|
||||
} else {
|
||||
console.log("No server found for " + storage.ServerId );
|
||||
}
|
||||
}
|
||||
console.log("No storage found for " + eStorageId[i] );
|
||||
return "index.php?view=image&eid=" + eId[i] + '&fid='+frame + "&width=" + monitorCanvasObj[monId].width + "&height=" + monitorCanvasObj[monId].height;
|
||||
}
|
||||
} // end for
|
||||
|
@ -465,7 +475,6 @@ function setSpeed( speed_index ) {
|
|||
currentSpeed = parseFloat(speeds[speed_index]);
|
||||
speedIndex = speed_index;
|
||||
playSecsperInterval = Math.floor( 1000 * currentSpeed * currentDisplayInterval ) / 1000000;
|
||||
console.log("playSecsPerInterval: " + playSecsperInterval + " = currentspeed:" + currentSpeed + " * " + currentDisplayInterval + " /1000");
|
||||
showSpeed(speed_index);
|
||||
if ( timerInterval != currentDisplayInterval || currentSpeed == 0 ) timerFire(); // if the timer isn't firing we need to trigger it to update
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ var imageLoadTimesNeeded=15; // and how many we need
|
|||
var timeLabelsFractOfRow = 0.9;
|
||||
var eMonId = [];
|
||||
var eId = [];
|
||||
var eStorageId = [];
|
||||
var eStartSecs = [];
|
||||
var eEndSecs = [];
|
||||
var eventFrames = []; // this is going to presume all frames equal durationlength
|
||||
|
@ -43,7 +44,6 @@ $index = 0;
|
|||
$anyAlarms = false;
|
||||
|
||||
if ( ! $initialModeIsLive ) {
|
||||
Warning($eventsSql);
|
||||
$result = dbQuery( $eventsSql );
|
||||
if ( ! $result ) {
|
||||
Fatal('SQL-ERR');
|
||||
|
@ -56,6 +56,7 @@ Warning($eventsSql);
|
|||
if ( $maxTimeSecs < $event['CalcEndTimeSecs'] ) $maxTimeSecs = $event['CalcEndTimeSecs'];
|
||||
echo "
|
||||
eMonId[$index]=" . $event['MonitorId'] . ";
|
||||
eStorageId[$index]=".$event['StorageId'] . ";
|
||||
eId[$index]=" . $event['Id'] . ";
|
||||
eStartSecs[$index]=" . $event['StartTimeSecs'] . ";
|
||||
eEndSecs[$index]=" . $event['CalcEndTimeSecs'] . ";
|
||||
|
@ -146,7 +147,17 @@ if ( $mId > 0 ) {
|
|||
|
||||
echo "var maxScore=$maxScore;\n"; // used to skip frame load if we find no alarms.
|
||||
} // end if initialmodeislive
|
||||
echo "var monitorName = [];\n";
|
||||
|
||||
echo "var Storage = []\n";
|
||||
foreach ( Storage::find_all() as $Storage ) {
|
||||
echo 'Storage[' . $Storage->Id() . '] = ' . json_encode($Storage). ";\n";
|
||||
}
|
||||
echo "var Servers = []\n";
|
||||
foreach ( Server::find_all() as $Server ) {
|
||||
echo 'Servers[' . $Server->Id() . '] = ' . json_encode($Server). ";\n";
|
||||
}
|
||||
echo "
|
||||
var monitorName = [];\n";
|
||||
echo "var monitorLoading = [];\n";
|
||||
echo "var monitorImageObject = [];\n";
|
||||
echo "var monitorImageURL = [];\n";
|
||||
|
|
|
@ -94,7 +94,7 @@ if (isset($_REQUEST['minTime']) && isset($_REQUEST['maxTime']) && count($display
|
|||
// Note we round up just a bit on the end time as otherwise you get gaps, like 59.78 to 00 in the next second, which can give blank frames when moved through slowly.
|
||||
|
||||
$eventsSql = '
|
||||
SELECT E.Id,E.Name,UNIX_TIMESTAMP(E.StartTime) AS StartTimeSecs,
|
||||
SELECT E.Id,E.Name,E.StorageId,UNIX_TIMESTAMP(E.StartTime) AS StartTimeSecs,
|
||||
CASE WHEN E.EndTime IS NULL THEN (SELECT UNIX_TIMESTAMP(DATE_ADD(E.StartTime, Interval max(Delta)+0.5 Second)) FROM Frames F WHERE F.EventId=E.Id)
|
||||
ELSE UNIX_TIMESTAMP(E.EndTime)
|
||||
END AS CalcEndTimeSecs, E.Length,
|
||||
|
|
|
@ -194,7 +194,7 @@ foreach( array_map( 'basename', glob('skins/'.$current_skin.'/css/*',GLOB_ONLYDI
|
|||
</div>
|
||||
</form>
|
||||
<?php
|
||||
} else if ( $tab == "servers" ) { ?>
|
||||
} else if ( $tab == 'servers' ) { ?>
|
||||
<form name="serversForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<input type="hidden" name="tab" value="<?php echo $tab ?>"/>
|
||||
|
@ -249,6 +249,7 @@ foreach( array_map( 'basename', glob('skins/'.$current_skin.'/css/*',GLOB_ONLYDI
|
|||
<th class="colPath"><?php echo translate('path') ?></th>
|
||||
<th class="colType"><?php echo translate('Type') ?></th>
|
||||
<th class="colScheme"><?php echo translate('StorageScheme') ?></th>
|
||||
<th class="colServer"><?php echo translate('Server') ?></th>
|
||||
<th class="colMark"><?php echo translate('Mark') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -260,6 +261,9 @@ foreach( array_map( 'basename', glob('skins/'.$current_skin.'/css/*',GLOB_ONLYDI
|
|||
<td class="colPath"><?php echo makePopupLink( '?view=storage&id='.$row['Id'], 'zmStorage', 'storage', validHtmlStr($row['Path']), $canEdit ) ?></td>
|
||||
<td class="colType"><?php echo makePopupLink( '?view=storage&id='.$row['Id'], 'zmStorage', 'storage', validHtmlStr($row['Type']), $canEdit ) ?></td>
|
||||
<td class="colScheme"><?php echo makePopupLink( '?view=storage&id='.$row['Id'], 'zmStorage', 'storage', validHtmlStr($row['Scheme']), $canEdit ) ?></td>
|
||||
<td class="colServer"><?php
|
||||
$Server = new Server($row['ServerId']);
|
||||
echo makePopupLink( '?view=storage&id='.$row['Id'], 'zmStorage', 'storage', validHtmlStr($Server->Name()), $canEdit ) ?></td>
|
||||
<td class="colMark"><input type="checkbox" name="markIds[]" value="<?php echo $row['Id'] ?>" onclick="configureDeleteButton(this);"<?php if ( !$canEdit ) { ?> disabled="disabled"<?php } ?>/></td>
|
||||
</tr>
|
||||
<?php } #end foreach Server ?>
|
||||
|
|
|
@ -43,6 +43,11 @@ $scheme_options = array(
|
|||
'Shallow' => translate('Shallow'),
|
||||
);
|
||||
|
||||
$servers = Server::find_all();
|
||||
$ServersById = array();
|
||||
foreach ( $servers as $S ) {
|
||||
$ServersById[$S->Id()] = $S;
|
||||
}
|
||||
$focusWindow = true;
|
||||
|
||||
xhtmlHeaders(__FILE__, translate('Storage')." - ".$newStorage['Name'] );
|
||||
|
@ -67,6 +72,10 @@ xhtmlHeaders(__FILE__, translate('Storage')." - ".$newStorage['Name'] );
|
|||
<th scope="row"><?php echo translate('Path') ?></th>
|
||||
<td><input type="text" name="newStorage[Path]" value="<?php echo $newStorage['Path'] ?>"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('Server') ?></th>
|
||||
<td><?php echo htmlSelect( 'newStorage[ServerId]', array('','Remote') + $ServersById, $newStorage['ServerId'] ); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('Type') ?></th>
|
||||
<td><?php echo htmlSelect( 'newStorage[Type]', $type_options, $newStorage['Type'] ); ?></td>
|
||||
|
|
Loading…
Reference in New Issue