Merge branch 'storageareas' into zma_to_thread
This commit is contained in:
commit
834dfbfe0c
|
@ -2,3 +2,6 @@
|
||||||
path = web/api/app/Plugin/Crud
|
path = web/api/app/Plugin/Crud
|
||||||
url = https://github.com/FriendsOfCake/crud.git
|
url = https://github.com/FriendsOfCake/crud.git
|
||||||
branch = 3.0
|
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 `MonitorId` (`MonitorId`),
|
||||||
KEY `StartTime` (`StartTime`),
|
KEY `StartTime` (`StartTime`),
|
||||||
KEY `Frames` (`Frames`),
|
KEY `Frames` (`Frames`),
|
||||||
KEY `Archived` (`Archived`)
|
KEY `Archived` (`Archived`),
|
||||||
|
KEY `EndTime_DiskSpace` (`EndTime`,`DiskSpace`)
|
||||||
) ENGINE=@ZM_MYSQL_ENGINE@;
|
) ENGINE=@ZM_MYSQL_ENGINE@;
|
||||||
|
|
||||||
--
|
--
|
||||||
|
@ -277,7 +278,7 @@ CREATE TABLE `Groups` (
|
||||||
--Table structure for table `Groups_Monitors`
|
--Table structure for table `Groups_Monitors`
|
||||||
--
|
--
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `Groups_Monitors`
|
DROP TABLE IF EXISTS `Groups_Monitors`;
|
||||||
CREATE TABLE `Groups_Monitors` (
|
CREATE TABLE `Groups_Monitors` (
|
||||||
`Id` INT(10) unsigned NOT NULL auto_increment,
|
`Id` INT(10) unsigned NOT NULL auto_increment,
|
||||||
`GroupId` int(10) unsigned NOT NULL,
|
`GroupId` int(10) unsigned NOT NULL,
|
||||||
|
@ -640,6 +641,7 @@ CREATE TABLE `Storage` (
|
||||||
`Type` enum('local','s3fs') NOT NULL default 'local',
|
`Type` enum('local','s3fs') NOT NULL default 'local',
|
||||||
`DiskSpace` bigint unsigned default NULL,
|
`DiskSpace` bigint unsigned default NULL,
|
||||||
`Scheme enum('Deep','Medium','Shallow') NOT NULL default 'Medium',
|
`Scheme enum('Deep','Medium','Shallow') NOT NULL default 'Medium',
|
||||||
|
`ServerId` int(10) unsigned,
|
||||||
PRIMARY KEY (`Id`)
|
PRIMARY KEY (`Id`)
|
||||||
) ENGINE=@ZM_MYSQL_ENGINE@;
|
) 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
|
-- 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
|
-- 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} ) {
|
if ( ! $$event{Path} ) {
|
||||||
my $Storage = $event->Storage();
|
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{Scheme} eq 'Deep' ) {
|
||||||
if ( $event->Time() ) {
|
if ( $event->Time() ) {
|
||||||
$$event{Path} = join('/',
|
$$event{RelativePath} = join('/',
|
||||||
$Storage->Path(),
|
|
||||||
$event->{MonitorId},
|
$event->{MonitorId},
|
||||||
strftime( '%y/%m/%d/%H/%M/%S',
|
strftime( '%y/%m/%d/%H/%M/%S',
|
||||||
localtime($event->Time())
|
localtime($event->Time())
|
||||||
|
@ -166,30 +176,28 @@ sub Path {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
Error("Event $$event{Id} has no value for Time(), unable to determine path");
|
Error("Event $$event{Id} has no value for Time(), unable to determine path");
|
||||||
$$event{Path} = '';
|
$$event{RelativePath} = '';
|
||||||
}
|
}
|
||||||
} elsif ( $$event{Scheme} eq 'Medium' ) {
|
} elsif ( $$event{Scheme} eq 'Medium' ) {
|
||||||
if ( $event->Time() ) {
|
if ( $event->Time() ) {
|
||||||
$$event{Path} = join('/',
|
$$event{RelativePath} = join('/',
|
||||||
$Storage->Path(),
|
|
||||||
$event->{MonitorId},
|
$event->{MonitorId},
|
||||||
strftime( '%Y-%m-%d', localtime($event->Time())),
|
strftime( '%Y-%m-%d', localtime($event->Time())),
|
||||||
$event->{Id},
|
$event->{Id},
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
Error("Event $$event{Id} has no value for Time(), unable to determine path");
|
Error("Event $$event{Id} has no value for Time(), unable to determine path");
|
||||||
$$event{Path} = '';
|
$$event{RelativePath} = '';
|
||||||
}
|
}
|
||||||
} else { # Shallow
|
} else { # Shallow
|
||||||
$$event{Path} = join('/',
|
$$event{RelativePath} = join('/',
|
||||||
$Storage->Path(),
|
|
||||||
$event->{MonitorId},
|
$event->{MonitorId},
|
||||||
$event->{Id},
|
$event->{Id},
|
||||||
);
|
);
|
||||||
} # end if Scheme
|
} # end if Scheme
|
||||||
} # end if ! Path
|
} # end if ! Path
|
||||||
|
|
||||||
return $$event{Path};
|
return $$event{RelativePath};
|
||||||
}
|
}
|
||||||
|
|
||||||
sub GenerateVideo {
|
sub GenerateVideo {
|
||||||
|
@ -337,7 +345,7 @@ sub delete_files {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Debug("Deleting files for Event $$event{Id} from $storage_path.");
|
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" );
|
#Debug( "LP1:$link_path" );
|
||||||
my @links = glob($link_path);
|
my @links = glob($link_path);
|
||||||
#Debug( "L:".$links[0].": $!" );
|
#Debug( "L:".$links[0].": $!" );
|
||||||
|
@ -371,7 +379,7 @@ sub delete_files {
|
||||||
}
|
}
|
||||||
} # end if links
|
} # end if links
|
||||||
} else {
|
} else {
|
||||||
my $command = "/bin/rm -rf ". $event->Path();
|
my $command = '/bin/rm -rf '. $storage_path . '/'. $event->RelativePath();
|
||||||
ZoneMinder::General::executeShellCommand( $command );
|
ZoneMinder::General::executeShellCommand( $command );
|
||||||
}
|
}
|
||||||
} # end sub delete_files
|
} # end sub delete_files
|
||||||
|
|
|
@ -238,8 +238,13 @@ MAIN: while( $loop ) {
|
||||||
} elsif ( $$Storage{Scheme} eq 'Medium' ) {
|
} elsif ( $$Storage{Scheme} eq 'Medium' ) {
|
||||||
foreach my $event_dir ( glob("$monitor_dir/*/*") ) {
|
foreach my $event_dir ( glob("$monitor_dir/*/*") ) {
|
||||||
next if ! -d $event_dir;
|
next if ! -d $event_dir;
|
||||||
my $Event = $fs_events->{$event} = new ZoneMinder::Event();
|
my ( $date, $event_id ) = $event_dir =~ /^$monitor_dir\/(\d{4}\-\d{2}\-\d{2})\/(\d\+)$/;
|
||||||
$$Event{Id} = $event;
|
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{Path} = $event_dir;
|
||||||
$Event->MonitorId( $monitor_dir );
|
$Event->MonitorId( $monitor_dir );
|
||||||
$Event->StorageId( $Storage->Id() );
|
$Event->StorageId( $Storage->Id() );
|
||||||
|
|
|
@ -70,6 +70,7 @@ Cache::config('default', array('engine' => 'Apc'));
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
CakePlugin::load('Crud');
|
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:
|
* 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 );
|
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) {
|
function process_configfile($configFile) {
|
||||||
if ( is_readable( $configFile ) ) {
|
if ( is_readable( $configFile ) ) {
|
||||||
$configvals = array();
|
$configvals = array();
|
||||||
|
|
|
@ -13,12 +13,15 @@ class MonitorsController extends AppController {
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public $components = array('Paginator', 'RequestHandler');
|
public $components = array('Paginator', 'RequestHandler');
|
||||||
|
|
||||||
|
public function beforeRender() {
|
||||||
|
$this->set($this->Monitor->enumValues());
|
||||||
|
}
|
||||||
public function beforeFilter() {
|
public function beforeFilter() {
|
||||||
parent::beforeFilter();
|
parent::beforeFilter();
|
||||||
$canView = $this->Session->Read('monitorPermission');
|
$canView = $this->Session->Read('monitorPermission');
|
||||||
if ($canView =='None') {
|
if ($canView == 'None') {
|
||||||
throw new UnauthorizedException(__('Insufficient Privileges'));
|
throw new UnauthorizedException(__('Insufficient Privileges'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -29,21 +32,21 @@ class MonitorsController extends AppController {
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function index() {
|
public function index() {
|
||||||
$this->Monitor->recursive = 0;
|
$this->Monitor->recursive = 0;
|
||||||
|
|
||||||
if ($this->request->params['named']) {
|
if ($this->request->params['named']) {
|
||||||
$this->FilterComponent = $this->Components->load('Filter');
|
$this->FilterComponent = $this->Components->load('Filter');
|
||||||
//$conditions = $this->FilterComponent->buildFilter($this->request->params['named']);
|
//$conditions = $this->FilterComponent->buildFilter($this->request->params['named']);
|
||||||
$conditions = $this->request->params['named'];
|
$conditions = $this->request->params['named'];
|
||||||
} else {
|
} else {
|
||||||
$conditions = array();
|
$conditions = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
$allowedMonitors=preg_split ('@,@', $this->Session->Read('allowedMonitors'),NULL, PREG_SPLIT_NO_EMPTY);
|
$allowedMonitors=preg_split ('@,@', $this->Session->Read('allowedMonitors'),NULL, PREG_SPLIT_NO_EMPTY);
|
||||||
if (!empty($allowedMonitors)) {
|
if (!empty($allowedMonitors)) {
|
||||||
$conditions['Monitor.Id' ] = $allowedMonitors;
|
$conditions['Monitor.Id' ] = $allowedMonitors;
|
||||||
}
|
}
|
||||||
$find_array = array('conditions'=>$conditions,'contain'=>array('Group'));
|
$find_array = array('conditions'=>$conditions,'contain'=>array('Group'));
|
||||||
|
|
||||||
if ( isset( $conditions['GroupId'] ) ) {
|
if ( isset( $conditions['GroupId'] ) ) {
|
||||||
|
@ -70,7 +73,7 @@ class MonitorsController extends AppController {
|
||||||
'monitors' => $monitors,
|
'monitors' => $monitors,
|
||||||
'_serialize' => array('monitors')
|
'_serialize' => array('monitors')
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* view method
|
* view method
|
||||||
|
@ -79,51 +82,57 @@ class MonitorsController extends AppController {
|
||||||
* @param string $id
|
* @param string $id
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function view($id = null) {
|
public function view($id = null) {
|
||||||
$this->Monitor->recursive = 0;
|
$this->Monitor->recursive = 0;
|
||||||
if (!$this->Monitor->exists($id)) {
|
if (!$this->Monitor->exists($id)) {
|
||||||
throw new NotFoundException(__('Invalid monitor'));
|
throw new NotFoundException(__('Invalid monitor'));
|
||||||
}
|
}
|
||||||
$allowedMonitors=preg_split ('@,@', $this->Session->Read('allowedMonitors'),NULL, PREG_SPLIT_NO_EMPTY);
|
$allowedMonitors=preg_split ('@,@', $this->Session->Read('allowedMonitors'),NULL, PREG_SPLIT_NO_EMPTY);
|
||||||
if (!empty($allowedMonitors)) {
|
if (!empty($allowedMonitors)) {
|
||||||
$restricted = array('Monitor.' . $this->Monitor->primaryKey => $allowedMonitors);
|
$restricted = array('Monitor.' . $this->Monitor->primaryKey => $allowedMonitors);
|
||||||
} else {
|
} else {
|
||||||
$restricted = '';
|
$restricted = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$options = array('conditions' => array(
|
$options = array('conditions' => array(
|
||||||
array('Monitor.' . $this->Monitor->primaryKey => $id),
|
array('Monitor.' . $this->Monitor->primaryKey => $id),
|
||||||
$restricted
|
$restricted
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$monitor = $this->Monitor->find('first', $options);
|
$monitor = $this->Monitor->find('first', $options);
|
||||||
$this->set(array(
|
$this->set(array(
|
||||||
'monitor' => $monitor,
|
'monitor' => $monitor,
|
||||||
'_serialize' => array('monitor')
|
'_serialize' => array('monitor')
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add method
|
* add method
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function add() {
|
public function add() {
|
||||||
if ($this->request->is('post')) {
|
if ( $this->request->is('post') ) {
|
||||||
|
|
||||||
if ($this->Session->Read('systemPermission') != 'Edit')
|
if ( $this->Session->Read('systemPermission') != 'Edit' ) {
|
||||||
{
|
throw new UnauthorizedException(__('Insufficient privileges'));
|
||||||
throw new UnauthorizedException(__('Insufficient privileges'));
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$this->Monitor->create();
|
$this->Monitor->create();
|
||||||
if ($this->Monitor->save($this->request->data)) {
|
if ($this->Monitor->save($this->request->data)) {
|
||||||
$this->daemonControl($this->Monitor->id, 'start');
|
$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')
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* edit method
|
* edit method
|
||||||
|
@ -132,40 +141,38 @@ class MonitorsController extends AppController {
|
||||||
* @param string $id
|
* @param string $id
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function edit($id = null) {
|
public function edit($id = null) {
|
||||||
$this->Monitor->id = $id;
|
$this->Monitor->id = $id;
|
||||||
|
|
||||||
if (!$this->Monitor->exists($id)) {
|
if (!$this->Monitor->exists($id)) {
|
||||||
throw new NotFoundException(__('Invalid monitor'));
|
throw new NotFoundException(__('Invalid monitor'));
|
||||||
}
|
}
|
||||||
if ($this->Session->Read('monitorPermission') != 'Edit')
|
if ($this->Session->Read('monitorPermission') != 'Edit') {
|
||||||
{
|
throw new UnauthorizedException(__('Insufficient privileges'));
|
||||||
throw new UnauthorizedException(__('Insufficient privileges'));
|
return;
|
||||||
return;
|
}
|
||||||
}
|
if ($this->Monitor->save($this->request->data)) {
|
||||||
if ($this->Monitor->save($this->request->data)) {
|
$message = 'Saved';
|
||||||
$message = 'Saved';
|
} else {
|
||||||
} else {
|
$message = 'Error';
|
||||||
$message = 'Error';
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$this->set(array(
|
$this->set(array(
|
||||||
'message' => $message,
|
'message' => $message,
|
||||||
'_serialize' => array('message')
|
'_serialize' => array('message')
|
||||||
));
|
));
|
||||||
|
|
||||||
// - restart or stop this monitor after change
|
// - restart or stop this monitor after change
|
||||||
$func = $this->Monitor->find('first', array(
|
$func = $this->Monitor->find('first', array(
|
||||||
'fields' => array('Function'),
|
'fields' => array('Function'),
|
||||||
'conditions' => array('Id' => $id)
|
'conditions' => array('Id' => $id)
|
||||||
))['Monitor']['Function'];
|
))['Monitor']['Function'];
|
||||||
// We don't pass the request data as the monitor object because it may be a subset of the full monitor array
|
// 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' );
|
||||||
$this->daemonControl( $this->Monitor->id, 'stop' );
|
if ( ( $func != 'None' ) and ( $this->Monitor->ServerId == ZM_SERVER_ID ) ) {
|
||||||
} else {
|
$this->daemonControl( $this->Monitor->id, 'start' );
|
||||||
$this->daemonControl( $this->Monitor->id, 'restart' );
|
|
||||||
}
|
}
|
||||||
}
|
} // end function edit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* delete method
|
* delete method
|
||||||
|
@ -174,196 +181,183 @@ class MonitorsController extends AppController {
|
||||||
* @param string $id
|
* @param string $id
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function delete($id = null) {
|
public function delete($id = null) {
|
||||||
$this->Monitor->id = $id;
|
$this->Monitor->id = $id;
|
||||||
if (!$this->Monitor->exists()) {
|
if (!$this->Monitor->exists()) {
|
||||||
throw new NotFoundException(__('Invalid monitor'));
|
throw new NotFoundException(__('Invalid monitor'));
|
||||||
}
|
}
|
||||||
if ($this->Session->Read('systemPermission') != 'Edit')
|
if ($this->Session->Read('systemPermission') != 'Edit') {
|
||||||
{
|
throw new UnauthorizedException(__('Insufficient privileges'));
|
||||||
throw new UnauthorizedException(__('Insufficient privileges'));
|
return;
|
||||||
return;
|
}
|
||||||
}
|
$this->request->allowMethod('post', 'delete');
|
||||||
$this->request->allowMethod('post', 'delete');
|
|
||||||
|
|
||||||
$this->daemonControl($this->Monitor->id, 'stop');
|
$this->daemonControl($this->Monitor->id, 'stop');
|
||||||
|
|
||||||
if ($this->Monitor->delete()) {
|
if ($this->Monitor->delete()) {
|
||||||
return $this->flash(__('The monitor has been deleted.'), array('action' => 'index'));
|
return $this->flash(__('The monitor has been deleted.'), array('action' => 'index'));
|
||||||
} else {
|
} else {
|
||||||
return $this->flash(__('The monitor could not be deleted. Please, try again.'), array('action' => 'index'));
|
return $this->flash(__('The monitor could not be deleted. Please, try again.'), array('action' => 'index'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sourceTypes() {
|
public function sourceTypes() {
|
||||||
$sourceTypes = $this->Monitor->query("describe Monitors Type;");
|
$sourceTypes = $this->Monitor->query("describe Monitors Type;");
|
||||||
|
|
||||||
preg_match('/^enum\((.*)\)$/', $sourceTypes[0]['COLUMNS']['Type'], $matches);
|
preg_match('/^enum\((.*)\)$/', $sourceTypes[0]['COLUMNS']['Type'], $matches);
|
||||||
foreach( explode(',', $matches[1]) as $value ) {
|
foreach( explode(',', $matches[1]) as $value ) {
|
||||||
$enum[] = trim( $value, "'" );
|
$enum[] = trim( $value, "'" );
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->set(array(
|
$this->set(array(
|
||||||
'sourceTypes' => $enum,
|
'sourceTypes' => $enum,
|
||||||
'_serialize' => array('sourceTypes')
|
'_serialize' => array('sourceTypes')
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// arm/disarm alarms
|
// arm/disarm alarms
|
||||||
// expected format: http(s):/portal-api-url/monitors/alarm/id:M/command:C.json
|
// expected format: http(s):/portal-api-url/monitors/alarm/id:M/command:C.json
|
||||||
// where M=monitorId
|
// where M=monitorId
|
||||||
// where C=on|off|status
|
// where C=on|off|status
|
||||||
public function alarm()
|
public function alarm() {
|
||||||
{
|
$id = $this->request->params['named']['id'];
|
||||||
$id = $this->request->params['named']['id'];
|
$cmd = strtolower($this->request->params['named']['command']);
|
||||||
$cmd = strtolower($this->request->params['named']['command']);
|
if (!$this->Monitor->exists($id)) {
|
||||||
if (!$this->Monitor->exists($id)) {
|
throw new NotFoundException(__('Invalid monitor'));
|
||||||
throw new NotFoundException(__('Invalid monitor'));
|
}
|
||||||
}
|
if ( $cmd != 'on' && $cmd != 'off' && $cmd != 'status' ) {
|
||||||
if ( $cmd != 'on' && $cmd != 'off' && $cmd != 'status')
|
throw new BadRequestException(__('Invalid command'));
|
||||||
{
|
}
|
||||||
throw new BadRequestException(__('Invalid command'));
|
$zm_path_bin = Configure::read('ZM_PATH_BIN');
|
||||||
}
|
|
||||||
$zm_path_bin = Configure::read('ZM_PATH_BIN');
|
|
||||||
|
|
||||||
switch ($cmd)
|
switch ($cmd) {
|
||||||
{
|
case 'on':
|
||||||
case "on":
|
$q = '-a';
|
||||||
$q = '-a';
|
$verbose = '-v';
|
||||||
$verbose = "-v";
|
break;
|
||||||
break;
|
case 'off':
|
||||||
case "off":
|
$q = '-c';
|
||||||
$q = "-c";
|
$verbose = '-v';
|
||||||
$verbose = "-v";
|
break;
|
||||||
break;
|
case 'status':
|
||||||
case "status":
|
$verbose = ''; // zmu has a bug - gives incorrect verbose output in this case
|
||||||
$verbose = ""; // zmu has a bug - gives incorrect verbose output in this case
|
$q = '-s';
|
||||||
$q = "-s";
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// form auth key based on auth credentials
|
// form auth key based on auth credentials
|
||||||
$this->loadModel('Config');
|
$this->loadModel('Config');
|
||||||
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_OPT_USE_AUTH'));
|
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_OPT_USE_AUTH'));
|
||||||
$config = $this->Config->find('first', $options);
|
$config = $this->Config->find('first', $options);
|
||||||
$zmOptAuth = $config['Config']['Value'];
|
$zmOptAuth = $config['Config']['Value'];
|
||||||
|
|
||||||
|
|
||||||
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_RELAY'));
|
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_RELAY'));
|
||||||
$config = $this->Config->find('first', $options);
|
$config = $this->Config->find('first', $options);
|
||||||
$zmAuthRelay = $config['Config']['Value'];
|
$zmAuthRelay = $config['Config']['Value'];
|
||||||
|
|
||||||
$auth="";
|
$auth='';
|
||||||
if ($zmOptAuth)
|
if ( $zmOptAuth ) {
|
||||||
{
|
if ( $zmAuthRelay == 'hashed' ) {
|
||||||
if ($zmAuthRelay == 'hashed')
|
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_HASH_SECRET'));
|
||||||
{
|
$config = $this->Config->find('first', $options);
|
||||||
$options = array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_HASH_SECRET'));
|
$zmAuthHashSecret = $config['Config']['Value'];
|
||||||
$config = $this->Config->find('first', $options);
|
|
||||||
$zmAuthHashSecret = $config['Config']['Value'];
|
|
||||||
|
|
||||||
$time = localtime();
|
$time = localtime();
|
||||||
$ak = $zmAuthHashSecret.$this->Session->Read('username').$this->Session->Read('passwordHash').$time[2].$time[3].$time[4].$time[5];
|
$ak = $zmAuthHashSecret.$this->Session->Read('username').$this->Session->Read('passwordHash').$time[2].$time[3].$time[4].$time[5];
|
||||||
$ak = md5($ak);
|
$ak = md5($ak);
|
||||||
$auth = " -A ".$ak;
|
$auth = ' -A '.$ak;
|
||||||
}
|
} else if ( $zmAuthRelay == 'plain' ) {
|
||||||
elseif ($zmAuthRelay == 'plain')
|
$auth = ' -U ' .$this->Session->Read('username').' -P '.$this->Session->Read('password');
|
||||||
{
|
|
||||||
$auth = " -U " .$this->Session->Read('username')." -P ".$this->Session->Read('password');
|
|
||||||
|
|
||||||
}
|
} else if ( $zmAuthRelay == 'none' ) {
|
||||||
elseif ($zmAuthRelay == 'none')
|
$auth = ' -U ' .$this->Session->Read('username');
|
||||||
{
|
}
|
||||||
$auth = " -U " .$this->Session->Read('username');
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$shellcmd = escapeshellcmd("$zm_path_bin/zmu $verbose -m$id $q $auth");
|
$shellcmd = escapeshellcmd("$zm_path_bin/zmu $verbose -m$id $q $auth");
|
||||||
$status = exec ($shellcmd);
|
$status = exec ($shellcmd);
|
||||||
|
|
||||||
$this->set(array(
|
$this->set(array(
|
||||||
'status' => $status,
|
'status' => $status,
|
||||||
'_serialize' => array('status'),
|
'_serialize' => array('status'),
|
||||||
));
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a daemon is running for the monitor id
|
||||||
|
public function daemonStatus() {
|
||||||
|
$id = $this->request->params['named']['id'];
|
||||||
|
$daemon = $this->request->params['named']['daemon'];
|
||||||
|
|
||||||
}
|
if (!$this->Monitor->exists($id)) {
|
||||||
|
throw new NotFoundException(__('Invalid monitor'));
|
||||||
|
}
|
||||||
|
|
||||||
// Check if a daemon is running for the monitor id
|
$monitor = $this->Monitor->find('first', array(
|
||||||
public function daemonStatus() {
|
'fields' => array('Id', 'Type', 'Device'),
|
||||||
$id = $this->request->params['named']['id'];
|
'conditions' => array('Id' => $id)
|
||||||
$daemon = $this->request->params['named']['daemon'];
|
));
|
||||||
|
|
||||||
if (!$this->Monitor->exists($id)) {
|
// Clean up the returned array
|
||||||
throw new NotFoundException(__('Invalid monitor'));
|
$monitor = Set::extract('/Monitor/.', $monitor);
|
||||||
}
|
|
||||||
|
|
||||||
$monitor = $this->Monitor->find('first', array(
|
// Pass -d for local, otherwise -m
|
||||||
'fields' => array('Id', 'Type', 'Device'),
|
if ($monitor[0]['Type'] == 'Local') {
|
||||||
'conditions' => array('Id' => $id)
|
$args = '-d '. $monitor[0]['Device'];
|
||||||
));
|
} else {
|
||||||
|
$args = '-m '. $monitor[0]['Id'];
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up the returned array
|
// Build the command, and execute it
|
||||||
$monitor = Set::extract('/Monitor/.', $monitor);
|
$zm_path_bin = Configure::read('ZM_PATH_BIN');
|
||||||
|
$command = escapeshellcmd("$zm_path_bin/zmdc.pl status $daemon $args");
|
||||||
|
$status = exec( $command );
|
||||||
|
|
||||||
// Pass -d for local, otherwise -m
|
// If 'not' is present, the daemon is not running, so return false
|
||||||
if ($monitor[0]['Type'] == 'Local') {
|
// https://github.com/ZoneMinder/ZoneMinder/issues/799#issuecomment-108996075
|
||||||
$args = "-d ". $monitor[0]['Device'];
|
// Also sending back the status text so we can check if the monitor is in pending
|
||||||
} else {
|
// state which means there may be an error
|
||||||
$args = "-m ". $monitor[0]['Id'];
|
$statustext = $status;
|
||||||
}
|
$status = (strpos($status, 'not')) ? false : true;
|
||||||
|
|
||||||
// Build the command, and execute it
|
$this->set(array(
|
||||||
$zm_path_bin = Configure::read('ZM_PATH_BIN');
|
'status' => $status,
|
||||||
$command = escapeshellcmd("$zm_path_bin/zmdc.pl status $daemon $args");
|
'statustext' => $statustext,
|
||||||
$status = exec( $command );
|
'_serialize' => array('status','statustext'),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
// If 'not' is present, the daemon is not running, so return false
|
public function daemonControl($id, $command, $monitor=null, $daemon=null) {
|
||||||
// https://github.com/ZoneMinder/ZoneMinder/issues/799#issuecomment-108996075
|
$args = '';
|
||||||
// Also sending back the status text so we can check if the monitor is in pending
|
$daemons = array();
|
||||||
// state which means there may be an error
|
|
||||||
$statustext = $status;
|
|
||||||
$status = (strpos($status, 'not')) ? false : true;
|
|
||||||
|
|
||||||
$this->set(array(
|
if (!$monitor) {
|
||||||
'status' => $status,
|
// Need to see if it is local or remote
|
||||||
'statustext' => $statustext,
|
$monitor = $this->Monitor->find('first', array(
|
||||||
'_serialize' => array('status','statustext'),
|
'fields' => array('Type', 'Function'),
|
||||||
));
|
'conditions' => array('Id' => $id)
|
||||||
}
|
));
|
||||||
|
$monitor = $monitor['Monitor'];
|
||||||
|
}
|
||||||
|
|
||||||
public function daemonControl($id, $command, $monitor=null, $daemon=null) {
|
if ($monitor['Type'] == 'Local') {
|
||||||
$args = '';
|
$args = '-d ' . $monitor['Device'];
|
||||||
$daemons = array();
|
} else {
|
||||||
|
$args = '-m ' . $id;
|
||||||
|
}
|
||||||
|
|
||||||
if (!$monitor) {
|
if ($monitor['Function'] == 'Monitor') {
|
||||||
// Need to see if it is local or remote
|
array_push($daemons, 'zmc');
|
||||||
$monitor = $this->Monitor->find('first', array(
|
} else {
|
||||||
'fields' => array('Type', 'Function'),
|
array_push($daemons, 'zmc', 'zma');
|
||||||
'conditions' => array('Id' => $id)
|
}
|
||||||
));
|
|
||||||
$monitor = $monitor['Monitor'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($monitor['Type'] == 'Local') {
|
$zm_path_bin = Configure::read('ZM_PATH_BIN');
|
||||||
$args = "-d " . $monitor['Device'];
|
|
||||||
} else {
|
|
||||||
$args = "-m " . $id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($monitor['Function'] == 'Monitor') {
|
foreach ($daemons as $daemon) {
|
||||||
array_push($daemons, 'zmc');
|
$shellcmd = escapeshellcmd("$zm_path_bin/zmdc.pl $command $daemon $args");
|
||||||
} else {
|
$status = exec( $shellcmd );
|
||||||
array_push($daemons, 'zmc', 'zma');
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$zm_path_bin = Configure::read('ZM_PATH_BIN');
|
|
||||||
|
|
||||||
foreach ($daemons as $daemon) {
|
|
||||||
$shellcmd = escapeshellcmd("$zm_path_bin/zmdc.pl $command $daemon $args");
|
|
||||||
$status = exec( $shellcmd );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
} // end class MonitorsController
|
||||||
|
|
|
@ -86,10 +86,10 @@ class Monitor extends AppModel {
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * hasMany associations
|
* hasMany associations
|
||||||
* *
|
*
|
||||||
* * @var array
|
* @var array
|
||||||
* */
|
*/
|
||||||
public $hasAndBelongsToMany = array(
|
public $hasAndBelongsToMany = array(
|
||||||
'Group' => array(
|
'Group' => array(
|
||||||
'className' => 'Group',
|
'className' => 'Group',
|
||||||
|
@ -108,5 +108,16 @@ class Monitor extends AppModel {
|
||||||
'counterQuery' => ''
|
'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='&' ) {
|
public function getStreamSrc( $args=array(), $querySep='&' ) {
|
||||||
if ( $this->{'DefaultVideo'} and $args['mode'] != 'jpeg' ) {
|
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;
|
$streamSrc = ZM_BASE_URL.ZM_PATH_ZMS;
|
||||||
|
|
|
@ -295,8 +295,8 @@ private $control_fields = array(
|
||||||
}
|
}
|
||||||
return $filters;
|
return $filters;
|
||||||
}
|
}
|
||||||
public function save( $new_values = null ) {
|
|
||||||
|
|
||||||
|
public function save( $new_values = null ) {
|
||||||
|
|
||||||
if ( $new_values ) {
|
if ( $new_values ) {
|
||||||
foreach ( $new_values as $k=>$v ) {
|
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=?';
|
$fields = array_keys( $this->defaults );
|
||||||
$values = array_map( function($field){return $this->{$field};}, $this->fields );
|
|
||||||
|
$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'};
|
$values[] = $this->{'Id'};
|
||||||
dbQuery( $sql, $values );
|
dbQuery( $sql, $values );
|
||||||
} // end function save
|
} // end function save
|
||||||
|
|
|
@ -70,15 +70,38 @@ class Storage {
|
||||||
Warning( "Unknown function call Storage->$fn from $file:$line" );
|
Warning( "Unknown function call Storage->$fn from $file:$line" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static function find_all() {
|
public static function find_all( $parameters = null, $options = null ) {
|
||||||
$storage_areas = array();
|
$filters = array();
|
||||||
$result = dbQuery( 'SELECT * FROM Storage ORDER BY Name');
|
$sql = 'SELECT * FROM Storage ';
|
||||||
$results = $result->fetchALL(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Storage' );
|
$values = array();
|
||||||
foreach ( $results as $row => $obj ) {
|
|
||||||
$storage_areas[] = $obj;
|
if ( $parameters ) {
|
||||||
$storage_cache[$obj->Id()] = $obj;
|
$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 );
|
||||||
}
|
}
|
||||||
return $storage_areas;
|
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 ) {
|
||||||
|
$filters[] = $obj;
|
||||||
|
}
|
||||||
|
return $filters;
|
||||||
}
|
}
|
||||||
public function disk_usage_percent() {
|
public function disk_usage_percent() {
|
||||||
$path = $this->Path();
|
$path = $this->Path();
|
||||||
|
@ -95,11 +118,8 @@ class Storage {
|
||||||
Error("disk_total_space returned false for " . $path );
|
Error("disk_total_space returned false for " . $path );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
$free = disk_free_space( $path );
|
$used = $this->disk_used_space();
|
||||||
if ( ! $free ) {
|
$usage = round( ($used / $total) * 100);
|
||||||
Error("disk_free_space returned false for " . $path );
|
|
||||||
}
|
|
||||||
$usage = round(($total - $free) / $total * 100);
|
|
||||||
return $usage;
|
return $usage;
|
||||||
}
|
}
|
||||||
public function disk_total_space() {
|
public function disk_total_space() {
|
||||||
|
|
|
@ -1280,6 +1280,7 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) {
|
||||||
$filter['sql'] .= ' not regexp '.$value;
|
$filter['sql'] .= ' not regexp '.$value;
|
||||||
break;
|
break;
|
||||||
case '=[]' :
|
case '=[]' :
|
||||||
|
case 'IN' :
|
||||||
$filter['sql'] .= ' in ('.join( ',', $valueList ).')';
|
$filter['sql'] .= ' in ('.join( ',', $valueList ).')';
|
||||||
break;
|
break;
|
||||||
case '![]' :
|
case '![]' :
|
||||||
|
|
|
@ -320,7 +320,10 @@ 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="'.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>'; };
|
#$func = function($S){ return '<span title="">'.$S->Name() . ': ' . $S->disk_usage_percent().'%' . '</span>'; };
|
||||||
echo implode( ', ', array_map ( $func, $storage_areas ) );
|
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).'%';
|
echo ' ' . ZM_PATH_MAP .': '. getDiskPercent(ZM_PATH_MAP).'%';
|
||||||
?></li>
|
?></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -37,7 +37,7 @@ $eventCounts = array(
|
||||||
'filter' => array(
|
'filter' => array(
|
||||||
'Query' => array(
|
'Query' => array(
|
||||||
'terms' => 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] ) {
|
if ( eMonId[i] == monId && time >= eStartSecs[i] && time <= eEndSecs[i] ) {
|
||||||
var duration = eEndSecs[i]-eStartSecs[i];
|
var duration = eEndSecs[i]-eStartSecs[i];
|
||||||
var frame = parseInt((time - eStartSecs[i])/(duration)*eventFrames[i])+1;
|
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;
|
return "index.php?view=image&eid=" + eId[i] + '&fid='+frame + "&width=" + monitorCanvasObj[monId].width + "&height=" + monitorCanvasObj[monId].height;
|
||||||
}
|
}
|
||||||
} // end for
|
} // end for
|
||||||
|
@ -465,7 +475,6 @@ function setSpeed( speed_index ) {
|
||||||
currentSpeed = parseFloat(speeds[speed_index]);
|
currentSpeed = parseFloat(speeds[speed_index]);
|
||||||
speedIndex = speed_index;
|
speedIndex = speed_index;
|
||||||
playSecsperInterval = Math.floor( 1000 * currentSpeed * currentDisplayInterval ) / 1000000;
|
playSecsperInterval = Math.floor( 1000 * currentSpeed * currentDisplayInterval ) / 1000000;
|
||||||
console.log("playSecsPerInterval: " + playSecsperInterval + " = currentspeed:" + currentSpeed + " * " + currentDisplayInterval + " /1000");
|
|
||||||
showSpeed(speed_index);
|
showSpeed(speed_index);
|
||||||
if ( timerInterval != currentDisplayInterval || currentSpeed == 0 ) timerFire(); // if the timer isn't firing we need to trigger it to update
|
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 timeLabelsFractOfRow = 0.9;
|
||||||
var eMonId = [];
|
var eMonId = [];
|
||||||
var eId = [];
|
var eId = [];
|
||||||
|
var eStorageId = [];
|
||||||
var eStartSecs = [];
|
var eStartSecs = [];
|
||||||
var eEndSecs = [];
|
var eEndSecs = [];
|
||||||
var eventFrames = []; // this is going to presume all frames equal durationlength
|
var eventFrames = []; // this is going to presume all frames equal durationlength
|
||||||
|
@ -43,7 +44,6 @@ $index = 0;
|
||||||
$anyAlarms = false;
|
$anyAlarms = false;
|
||||||
|
|
||||||
if ( ! $initialModeIsLive ) {
|
if ( ! $initialModeIsLive ) {
|
||||||
Warning($eventsSql);
|
|
||||||
$result = dbQuery( $eventsSql );
|
$result = dbQuery( $eventsSql );
|
||||||
if ( ! $result ) {
|
if ( ! $result ) {
|
||||||
Fatal('SQL-ERR');
|
Fatal('SQL-ERR');
|
||||||
|
@ -56,6 +56,7 @@ Warning($eventsSql);
|
||||||
if ( $maxTimeSecs < $event['CalcEndTimeSecs'] ) $maxTimeSecs = $event['CalcEndTimeSecs'];
|
if ( $maxTimeSecs < $event['CalcEndTimeSecs'] ) $maxTimeSecs = $event['CalcEndTimeSecs'];
|
||||||
echo "
|
echo "
|
||||||
eMonId[$index]=" . $event['MonitorId'] . ";
|
eMonId[$index]=" . $event['MonitorId'] . ";
|
||||||
|
eStorageId[$index]=".$event['StorageId'] . ";
|
||||||
eId[$index]=" . $event['Id'] . ";
|
eId[$index]=" . $event['Id'] . ";
|
||||||
eStartSecs[$index]=" . $event['StartTimeSecs'] . ";
|
eStartSecs[$index]=" . $event['StartTimeSecs'] . ";
|
||||||
eEndSecs[$index]=" . $event['CalcEndTimeSecs'] . ";
|
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.
|
echo "var maxScore=$maxScore;\n"; // used to skip frame load if we find no alarms.
|
||||||
} // end if initialmodeislive
|
} // 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 monitorLoading = [];\n";
|
||||||
echo "var monitorImageObject = [];\n";
|
echo "var monitorImageObject = [];\n";
|
||||||
echo "var monitorImageURL = [];\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.
|
// 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 = '
|
$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)
|
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)
|
ELSE UNIX_TIMESTAMP(E.EndTime)
|
||||||
END AS CalcEndTimeSecs, E.Length,
|
END AS CalcEndTimeSecs, E.Length,
|
||||||
|
|
|
@ -194,7 +194,7 @@ foreach( array_map( 'basename', glob('skins/'.$current_skin.'/css/*',GLOB_ONLYDI
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<?php
|
<?php
|
||||||
} else if ( $tab == "servers" ) { ?>
|
} else if ( $tab == 'servers' ) { ?>
|
||||||
<form name="serversForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
<form name="serversForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||||
<input type="hidden" name="tab" value="<?php echo $tab ?>"/>
|
<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="colPath"><?php echo translate('path') ?></th>
|
||||||
<th class="colType"><?php echo translate('Type') ?></th>
|
<th class="colType"><?php echo translate('Type') ?></th>
|
||||||
<th class="colScheme"><?php echo translate('StorageScheme') ?></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>
|
<th class="colMark"><?php echo translate('Mark') ?></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</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="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="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="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>
|
<td class="colMark"><input type="checkbox" name="markIds[]" value="<?php echo $row['Id'] ?>" onclick="configureDeleteButton(this);"<?php if ( !$canEdit ) { ?> disabled="disabled"<?php } ?>/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php } #end foreach Server ?>
|
<?php } #end foreach Server ?>
|
||||||
|
|
|
@ -43,6 +43,11 @@ $scheme_options = array(
|
||||||
'Shallow' => translate('Shallow'),
|
'Shallow' => translate('Shallow'),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$servers = Server::find_all();
|
||||||
|
$ServersById = array();
|
||||||
|
foreach ( $servers as $S ) {
|
||||||
|
$ServersById[$S->Id()] = $S;
|
||||||
|
}
|
||||||
$focusWindow = true;
|
$focusWindow = true;
|
||||||
|
|
||||||
xhtmlHeaders(__FILE__, translate('Storage')." - ".$newStorage['Name'] );
|
xhtmlHeaders(__FILE__, translate('Storage')." - ".$newStorage['Name'] );
|
||||||
|
@ -67,6 +72,10 @@ xhtmlHeaders(__FILE__, translate('Storage')." - ".$newStorage['Name'] );
|
||||||
<th scope="row"><?php echo translate('Path') ?></th>
|
<th scope="row"><?php echo translate('Path') ?></th>
|
||||||
<td><input type="text" name="newStorage[Path]" value="<?php echo $newStorage['Path'] ?>"/></td>
|
<td><input type="text" name="newStorage[Path]" value="<?php echo $newStorage['Path'] ?>"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row"><?php echo translate('Server') ?></th>
|
||||||
|
<td><?php echo htmlSelect( 'newStorage[ServerId]', array('','Remote') + $ServersById, $newStorage['ServerId'] ); ?></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('Type') ?></th>
|
<th scope="row"><?php echo translate('Type') ?></th>
|
||||||
<td><?php echo htmlSelect( 'newStorage[Type]', $type_options, $newStorage['Type'] ); ?></td>
|
<td><?php echo htmlSelect( 'newStorage[Type]', $type_options, $newStorage['Type'] ); ?></td>
|
||||||
|
|
Loading…
Reference in New Issue