Merge branch 'storageareas' of github.com:ConnorTechnology/ZoneMinder into storageareas
This commit is contained in:
commit
8312bf52a4
|
@ -232,6 +232,7 @@ CREATE TABLE `Filters` (
|
||||||
`AutoExecute` tinyint(3) unsigned NOT NULL default '0',
|
`AutoExecute` tinyint(3) unsigned NOT NULL default '0',
|
||||||
`AutoExecuteCmd` tinytext,
|
`AutoExecuteCmd` tinytext,
|
||||||
`AutoDelete` tinyint(3) unsigned NOT NULL default '0',
|
`AutoDelete` tinyint(3) unsigned NOT NULL default '0',
|
||||||
|
`UpdateDiskSpace` tinyint(3) unsigned NOT NULL default '0',
|
||||||
`Background` tinyint(1) unsigned NOT NULL default '0',
|
`Background` tinyint(1) unsigned NOT NULL default '0',
|
||||||
`Concurrent` tinyint(1) unsigned NOT NULL default '0',
|
`Concurrent` tinyint(1) unsigned NOT NULL default '0',
|
||||||
PRIMARY KEY (`Id`),
|
PRIMARY KEY (`Id`),
|
||||||
|
@ -288,6 +289,8 @@ CREATE TABLE `Logs` (
|
||||||
KEY `TimeKey` (`TimeKey`)
|
KEY `TimeKey` (`TimeKey`)
|
||||||
) ENGINE=@ZM_MYSQL_ENGINE@;
|
) ENGINE=@ZM_MYSQL_ENGINE@;
|
||||||
|
|
||||||
|
CREATE INDEX `Logs_TimeKey_idx` ON `Logs` (`TimeKey`);
|
||||||
|
CREATE INDEX `Logs_Level_idx` ON `Logs` (`Level`);
|
||||||
--
|
--
|
||||||
-- Table structure for table `Manufacturers`
|
-- Table structure for table `Manufacturers`
|
||||||
--
|
--
|
||||||
|
@ -402,7 +405,7 @@ CREATE TABLE `Monitors` (
|
||||||
`SectionLength` int(10) unsigned NOT NULL default '600',
|
`SectionLength` int(10) unsigned NOT NULL default '600',
|
||||||
`FrameSkip` smallint(5) unsigned NOT NULL default '0',
|
`FrameSkip` smallint(5) unsigned NOT NULL default '0',
|
||||||
`MotionFrameSkip` smallint(5) unsigned NOT NULL default '0',
|
`MotionFrameSkip` smallint(5) unsigned NOT NULL default '0',
|
||||||
`AnalysisFPS` decimal(5,2) default NULL,
|
`AnalysisFPSLimit` decimal(5,2) default NULL,
|
||||||
`AnalysisUpdateDelay` smallint(5) unsigned NOT NULL default '0',
|
`AnalysisUpdateDelay` smallint(5) unsigned NOT NULL default '0',
|
||||||
`MaxFPS` decimal(5,2) default NULL,
|
`MaxFPS` decimal(5,2) default NULL,
|
||||||
`AlarmMaxFPS` decimal(5,2) default NULL,
|
`AlarmMaxFPS` decimal(5,2) default NULL,
|
||||||
|
@ -425,6 +428,9 @@ CREATE TABLE `Monitors` (
|
||||||
`WebColour` varchar(32) NOT NULL default 'red',
|
`WebColour` varchar(32) NOT NULL default 'red',
|
||||||
`Exif` tinyint(1) unsigned NOT NULL default '0',
|
`Exif` tinyint(1) unsigned NOT NULL default '0',
|
||||||
`Sequence` smallint(5) unsigned default NULL,
|
`Sequence` smallint(5) unsigned default NULL,
|
||||||
|
`Status` enum('Unknown','NotRunning','Running','NoSignal','Signal') NOT NULL default 'Unknown',
|
||||||
|
`zmcFPS` DECIMAL(5,2) NOT NULL default 0,
|
||||||
|
`zmaFPS` DECIMAL(5,2) NOT NULL default 0,
|
||||||
PRIMARY KEY (`Id`)
|
PRIMARY KEY (`Id`)
|
||||||
) ENGINE=@ZM_MYSQL_ENGINE@;
|
) ENGINE=@ZM_MYSQL_ENGINE@;
|
||||||
|
|
||||||
|
@ -457,6 +463,12 @@ CREATE TABLE `Servers` (
|
||||||
`Hostname` TEXT,
|
`Hostname` TEXT,
|
||||||
`Name` varchar(64) NOT NULL default '',
|
`Name` varchar(64) NOT NULL default '',
|
||||||
`State_Id` int(10) unsigned,
|
`State_Id` int(10) unsigned,
|
||||||
|
`Status` enum('Unknown','NotRunning','Running') NOT NULL default 'Unknown',
|
||||||
|
`Load` DECIMAL(5,1),
|
||||||
|
`TotalMem` bigint unsigned default null,
|
||||||
|
`FreeMem` bigint unsigned default null,
|
||||||
|
`TotalSwap` bigint unsigned default null,
|
||||||
|
`FreeSwap` bigint unsigned default null,
|
||||||
PRIMARY KEY (`Id`)
|
PRIMARY KEY (`Id`)
|
||||||
) ENGINE=@ZM_MYSQL_ENGINE@;
|
) ENGINE=@ZM_MYSQL_ENGINE@;
|
||||||
|
|
||||||
|
@ -741,6 +753,29 @@ INSERT INTO ZonePresets VALUES (5,'Best, low sensitivity','Active','Percent','Bl
|
||||||
INSERT INTO ZonePresets VALUES (6,'Best, medium sensitivity','Active','Percent','Blobs',40,NULL,16,NULL,5,5,12,NULL,10,NULL,1,NULL,0,0);
|
INSERT INTO ZonePresets VALUES (6,'Best, medium sensitivity','Active','Percent','Blobs',40,NULL,16,NULL,5,5,12,NULL,10,NULL,1,NULL,0,0);
|
||||||
INSERT INTO ZonePresets VALUES (7,'Best, high sensitivity','Active','Percent','Blobs',20,NULL,8,NULL,3,3,6,NULL,5,NULL,1,NULL,0,0);
|
INSERT INTO ZonePresets VALUES (7,'Best, high sensitivity','Active','Percent','Blobs',20,NULL,8,NULL,3,3,6,NULL,5,NULL,1,NULL,0,0);
|
||||||
|
|
||||||
|
CREATE TABLE Maps (
|
||||||
|
`Id` int(10) unsigned NOT NULL auto_increment,
|
||||||
|
`Name` TEXT NOT NULL,
|
||||||
|
`Filename` TEXT NOT NULL default '',
|
||||||
|
`NumCoords` tinyint(3) unsigned NOT NULL default '0',
|
||||||
|
`Coords` tinytext NOT NULL,
|
||||||
|
`ParentId` int(1) unsigned,
|
||||||
|
PRIMARY KEY (`Id`)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE MontageLayouts (
|
||||||
|
`Id` int(10) unsigned NOT NULL auto_increment,
|
||||||
|
`Name` TEXT NOT NULL,
|
||||||
|
`Positions` JSON,
|
||||||
|
PRIMARY KEY (`Id`)
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO MontageLayouts (`Name`,`Positions`) VALUES ('Freeform', '{ "default":{"float":"left"} }' );
|
||||||
|
INSERT INTO MontageLayouts (`Name`,`Positions`) VALUES ('2 Wide', '{ "default":{"float":"left", "width":"49%"} }' );
|
||||||
|
INSERT INTO MontageLayouts (`Name`,`Positions`) VALUES ('3 Wide', '{ "default":{"float":"left", "width":"33%"} }' );
|
||||||
|
INSERT INTO MontageLayouts (`Name`,`Positions`) VALUES ('4 Wide', '{ "default":{"float":"left", "width":"24.5%"} }' );
|
||||||
|
INSERT INTO MontageLayouts (`Name`,`Positions`) VALUES ('5 Wide', '{ "default":{"float":"left", "width":"19%"} }' );
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Apply the initial configuration
|
-- Apply the initial configuration
|
||||||
--
|
--
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
--
|
||||||
|
-- Add Type column to Storage
|
||||||
|
--
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Servers'
|
||||||
|
AND column_name = 'Status'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column Status already exists in Servers'",
|
||||||
|
"ALTER TABLE Servers ADD `Status` enum('Unknown','NotRunning','Running') NOT NULL default 'Unknown' AFTER `State_Id`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Servers'
|
||||||
|
AND column_name = 'CpuLoad'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column CpuLoad already exists in Servers'",
|
||||||
|
"ALTER TABLE Servers ADD `CpuLoad` DECIMAL(5,1) default NULL AFTER `Status`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Servers'
|
||||||
|
AND column_name = 'TotalMem'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column TotalMem already exists in Servers'",
|
||||||
|
"ALTER TABLE Servers ADD `TotalMem` bigint unsigned default null AFTER `CpuLoad`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Servers'
|
||||||
|
AND column_name = 'FreeMem'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column FreeMem already exists in Servers'",
|
||||||
|
"ALTER TABLE Servers ADD `FreeMem` bigint unsigned default null AFTER `TotalMem`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Servers'
|
||||||
|
AND column_name = 'TotalSwap'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column TotalSwap already exists in Servers'",
|
||||||
|
"ALTER TABLE Servers ADD `TotalSwap` bigint unsigned default null AFTER `FreeMem`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Servers'
|
||||||
|
AND column_name = 'FreeSwap'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column FreeSwap already exists in Servers'",
|
||||||
|
"ALTER TABLE Servers ADD `FreeSwap` bigint unsigned default null AFTER `TotalSwap`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Monitors'
|
||||||
|
AND column_name = 'Status'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column Status already exists in Monitors'",
|
||||||
|
"ALTER TABLE Monitors ADD `Status` enum('Unknown','NotRunning','Running','NoSignal','Signal') NOT NULL default 'Unknown' AFTER `Sequence`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Monitors'
|
||||||
|
AND column_name = 'CaptureFPS'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column CaptureFPS already exists in Monitors'",
|
||||||
|
"ALTER TABLE Monitors ADD `CaptureFPS` DECIMAL(10,2) NOT NULL default 0 AFTER `Status`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Monitors'
|
||||||
|
AND column_name = 'AnalysisFPSLimit'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column AnalysisFPSLimit already exists in Monitors'",
|
||||||
|
"ALTER TABLE Monitors CHANGE COLUMN `AnalysisFPS` `AnalysisFPSLimit` DECIMAL(5,2) default NULL"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Monitors'
|
||||||
|
AND column_name = 'AnalysisFPS'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column AnalysisFPS already exists in Monitors'",
|
||||||
|
"ALTER TABLE Monitors ADD `AnalysisFPS` DECIMAL(5,2) NOT NULL default 0 AFTER `CaptureFPS`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
|
@ -0,0 +1,69 @@
|
||||||
|
--
|
||||||
|
-- Add UpdateDiskSpace action to Filters
|
||||||
|
--
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Filters'
|
||||||
|
AND column_name = 'UpdateDiskSpace'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column UpdateDiskSpace already exists in Filters'",
|
||||||
|
"ALTER TABLE Filters ADD `UpdateDiskSpace` tinyint(3) unsigned NOT NULL default '0' AFTER `AutoDelete`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
--
|
||||||
|
-- Update Logs table to have some Indexes
|
||||||
|
--
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*)
|
||||||
|
FROM INFORMATION_SCHEMA.STATISTICS
|
||||||
|
WHERE table_name = 'Logs'
|
||||||
|
AND table_schema = DATABASE()
|
||||||
|
AND index_name = 'Logs_TimeKey_idx'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Logs_TimeKey_idx already exists on Logs table'",
|
||||||
|
"CREATE INDEX `Logs_TimeKey_idx` ON `Logs` (`TimeKey`)"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*)
|
||||||
|
FROM INFORMATION_SCHEMA.STATISTICS
|
||||||
|
WHERE table_name = 'Logs'
|
||||||
|
AND table_schema = DATABASE()
|
||||||
|
AND index_name = 'Logs_Level_idx'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Logs_Level_idx already exists on Logs table'",
|
||||||
|
"CREATE INDEX `Logs_Level_idx` ON `Logs` (`Level`)"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Monitors'
|
||||||
|
AND column_name = 'OutputCodec'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column OutputCodec already exists in Monitors'",
|
||||||
|
"ALTER TABLE `Monitors` ADD `OutputCodec` enum('h264','mjpeg') AFTER `VideoWriter`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = 'Monitors'
|
||||||
|
AND column_name = 'OutputContainer'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Column OutputContainer already exists in Monitors'",
|
||||||
|
"ALTER TABLE `Monitors` ADD `OutputContainer` enum('mp4','mkv') AFTER `OutputCodec`"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
|
@ -0,0 +1,64 @@
|
||||||
|
--
|
||||||
|
-- This adds Manufacturers and Models
|
||||||
|
--
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*)
|
||||||
|
FROM INFORMATION_SCHEMA.TABLES
|
||||||
|
WHERE table_name = 'MontageLayouts'
|
||||||
|
AND table_schema = DATABASE()
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'MontageLayouts table exists'",
|
||||||
|
"
|
||||||
|
CREATE TABLE MontageLayouts (
|
||||||
|
`Id` int(10) unsigned NOT NULL auto_increment,
|
||||||
|
`Name` TEXT NOT NULL,
|
||||||
|
`Positions` JSON,
|
||||||
|
PRIMARY KEY (`Id`)
|
||||||
|
);
|
||||||
|
"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = ( SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM MontageLayouts WHERE Name='Freeform') > 0,
|
||||||
|
"SELECT 'Freeform already in layouts'",
|
||||||
|
"INSERT INTO MontageLayouts (`Name`,`Positions`) VALUES ('Freeform', '{ "default":{"float":"left"} }' );"
|
||||||
|
) );
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = ( SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM MontageLayouts WHERE Name='2 Wide') > 0,
|
||||||
|
"SELECT '2 Wide already in layouts'",
|
||||||
|
"INSERT INTO MontageLayouts (`Name`,`Positions`) VALUES ('2 Wide', '{ "default":{"float":"left", "width":"49%"} }' );";
|
||||||
|
) );
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = ( SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM MontageLayouts WHERE Name='3 Wide') > 0,
|
||||||
|
"SELECT '3 Wide already in layouts'",
|
||||||
|
"INSERT INTO MontageLayouts (`Name`,`Positions`) VALUES ('3 Wide', '{ "default":{"float":"left", "width":"33%"} }' );"
|
||||||
|
) );
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
|
||||||
|
SET @s = ( SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM MontageLayouts WHERE Name='4 Wide') > 0,
|
||||||
|
"SELECT '4 Wide already in layouts'",
|
||||||
|
"INSERT INTO MontageLayouts (`Name`,`Positions`) VALUES ('4 Wide', '{ "default":{"float":"left", "width":"24.5%"} }' );"
|
||||||
|
) );
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
||||||
|
SET @s = ( SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM MontageLayouts WHERE Name='5 Wide') > 0,
|
||||||
|
"SELECT '5 Wide already in layouts'",
|
||||||
|
"INSERT INTO MontageLayouts (`Name`,`Positions`) VALUES ('5 Wide', '{ "default":{"float":"left", "width":"19%"} }' );"
|
||||||
|
) );
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
|
@ -60,7 +60,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
|
||||||
,libsoap-wsdl-perl
|
,libsoap-wsdl-perl
|
||||||
,libio-socket-multicast-perl
|
,libio-socket-multicast-perl
|
||||||
,libdigest-sha-perl
|
,libdigest-sha-perl
|
||||||
,libsys-cpu-perl, libsys-meminfo-perl
|
,libsys-cpu-perl, libsys-cpuload-perl, libsys-meminfo-perl
|
||||||
,libdata-uuid-perl
|
,libdata-uuid-perl
|
||||||
,mysql-client | virtual-mysql-client
|
,mysql-client | virtual-mysql-client
|
||||||
,perl-modules
|
,perl-modules
|
||||||
|
|
|
@ -27,7 +27,9 @@ override_dh_auto_configure:
|
||||||
-DZM_CGIDIR="/usr/lib/zoneminder/cgi-bin" \
|
-DZM_CGIDIR="/usr/lib/zoneminder/cgi-bin" \
|
||||||
-DZM_DIR_EVENTS="/var/cache/zoneminder/events" \
|
-DZM_DIR_EVENTS="/var/cache/zoneminder/events" \
|
||||||
-DZM_DIR_IMAGES="/var/cache/zoneminder/images" \
|
-DZM_DIR_IMAGES="/var/cache/zoneminder/images" \
|
||||||
-DZM_PATH_ZMS="/zm/cgi-bin/nph-zms"
|
-DZM_PATH_ZMS="/zm/cgi-bin/nph-zms" \
|
||||||
|
-DZM_NO_CURL=1 \
|
||||||
|
-DZM_NO_LIBVLC=1
|
||||||
|
|
||||||
override_dh_clean:
|
override_dh_clean:
|
||||||
dh_clean $(MANPAGES1)
|
dh_clean $(MANPAGES1)
|
||||||
|
|
|
@ -14,7 +14,8 @@ ExecStart=/usr/bin/zmpkg.pl start
|
||||||
ExecReload=/usr/bin/zmpkg.pl restart
|
ExecReload=/usr/bin/zmpkg.pl restart
|
||||||
ExecStop=/usr/bin/zmpkg.pl stop
|
ExecStop=/usr/bin/zmpkg.pl stop
|
||||||
PIDFile=/var/run/zm/zm.pid
|
PIDFile=/var/run/zm/zm.pid
|
||||||
Restart=on-abnormal
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
Environment=TZ=:/etc/localtime
|
Environment=TZ=:/etc/localtime
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
|
|
|
@ -157,6 +157,16 @@ sub zmDbGetMonitors {
|
||||||
return( \@monitors );
|
return( \@monitors );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub zmSQLExecute {
|
||||||
|
my $sql = shift;
|
||||||
|
|
||||||
|
my $sth = $dbh->prepare_cached( $sql )
|
||||||
|
or croak( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||||
|
my $res = $sth->execute( @_ )
|
||||||
|
or croak( "Can't execute '$sql': ".$sth->errstr() );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
sub zmDbGetMonitor {
|
sub zmDbGetMonitor {
|
||||||
zmDbConnect();
|
zmDbConnect();
|
||||||
|
|
||||||
|
@ -195,6 +205,30 @@ sub zmDbGetMonitorAndControl {
|
||||||
return( $monitor );
|
return( $monitor );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub start_transaction {
|
||||||
|
#my ( $caller, undef, $line ) = caller;
|
||||||
|
#$openprint::log->debug("Called start_transaction from $caller : $line");
|
||||||
|
my $d = shift;
|
||||||
|
$d = $dbh if ! $d;
|
||||||
|
my $ac = $d->{AutoCommit};
|
||||||
|
$d->{AutoCommit} = 0;
|
||||||
|
return $ac;
|
||||||
|
} # end sub start_transaction
|
||||||
|
|
||||||
|
sub end_transaction {
|
||||||
|
#my ( $caller, undef, $line ) = caller;
|
||||||
|
#$openprint::log->debug("Called end_transaction from $caller : $line");
|
||||||
|
my ( $d, $ac ) = @_;
|
||||||
|
if ( ! defined $ac ) {
|
||||||
|
Error("Undefined ac");
|
||||||
|
}
|
||||||
|
$d = $dbh if ! $d;
|
||||||
|
if ( $ac ) {
|
||||||
|
#$log->debug("Committing");
|
||||||
|
$d->commit();
|
||||||
|
} # end if
|
||||||
|
$d->{AutoCommit} = $ac;
|
||||||
|
} # end sub end_transaction
|
||||||
1;
|
1;
|
||||||
__END__
|
__END__
|
||||||
# Below is stub documentation for your module. You'd better edit it!
|
# Below is stub documentation for your module. You'd better edit it!
|
||||||
|
|
|
@ -359,14 +359,16 @@ sub age {
|
||||||
return $_[0]{age};
|
return $_[0]{age};
|
||||||
}
|
}
|
||||||
|
|
||||||
sub DiskUsage {
|
sub DiskSpace {
|
||||||
if ( @_ > 1 ) {
|
if ( @_ > 1 ) {
|
||||||
$_[0]{DiskUsage} = $_[1];
|
Debug("Cleared DiskSpace, was $_[0]{DiskSpace}");
|
||||||
|
$_[0]{DiskSpace} = $_[1];
|
||||||
}
|
}
|
||||||
if ( ! defined $_[0]{DiskUsage} ) {
|
if ( ! defined $_[0]{DiskSpace} ) {
|
||||||
my $size = 0;
|
my $size = 0;
|
||||||
File::Find::find( { wanted=>sub { $size += -f $_ ? -s _ : 0 }, untaint=>1 }, $_[0]->Path() );
|
File::Find::find( { wanted=>sub { $size += -f $_ ? -s _ : 0 }, untaint=>1 }, $_[0]->Path() );
|
||||||
$_[0]{DiskUsage} = $size;
|
$_[0]{DiskSpace} = $size;
|
||||||
|
Debug("DiskSpace for event $_[0]{Id} at $_[0]{Path} Updated to $size bytes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ sub Execute {
|
||||||
push @results, $event;
|
push @results, $event;
|
||||||
}
|
}
|
||||||
$sth->finish();
|
$sth->finish();
|
||||||
Debug("Loaded " . @results . " events for filter $_[0]{Name} using query ($sql)");
|
Debug('Loaded ' . @results . " events for filter $_[0]{Name} using query ($sql)");
|
||||||
return @results;
|
return @results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,38 +147,59 @@ sub Sql {
|
||||||
foreach my $term ( @{$filter_expr->{terms}} ) {
|
foreach my $term ( @{$filter_expr->{terms}} ) {
|
||||||
|
|
||||||
if ( exists($term->{cnj}) ) {
|
if ( exists($term->{cnj}) ) {
|
||||||
$self->{Sql} .= " ".$term->{cnj}." ";
|
$self->{Sql} .= ' '.$term->{cnj}." ";
|
||||||
}
|
}
|
||||||
if ( exists($term->{obr}) ) {
|
if ( exists($term->{obr}) ) {
|
||||||
$self->{Sql} .= " ".str_repeat( "(", $term->{obr} )." ";
|
$self->{Sql} .= ' '.str_repeat( "(", $term->{obr} )." ";
|
||||||
}
|
}
|
||||||
my $value = $term->{val};
|
my $value = $term->{val};
|
||||||
my @value_list;
|
my @value_list;
|
||||||
if ( $term->{attr} ) {
|
if ( $term->{attr} ) {
|
||||||
if ( $term->{attr} =~ /^Monitor/ ) {
|
if ( $term->{attr} =~ /^Monitor/ ) {
|
||||||
my ( $temp_attr_name ) = $term->{attr} =~ /^Monitor(.+)$/;
|
my ( $temp_attr_name ) = $term->{attr} =~ /^Monitor(.+)$/;
|
||||||
$self->{Sql} .= "M.".$temp_attr_name;
|
$self->{Sql} .= 'M.'.$temp_attr_name;
|
||||||
} elsif ( $term->{attr} =~ /^Server/ ) {
|
} elsif ( $term->{attr} =~ /^Server/ ) {
|
||||||
$self->{Sql} .= "M.".$term->{attr};
|
$self->{Sql} .= 'M.'.$term->{attr};
|
||||||
|
|
||||||
|
# StartTime options
|
||||||
} elsif ( $term->{attr} eq 'DateTime' ) {
|
} elsif ( $term->{attr} eq 'DateTime' ) {
|
||||||
$self->{Sql} .= "E.StartTime";
|
$self->{Sql} .= 'E.StartTime';
|
||||||
|
} elsif ( $term->{attr} eq 'StartDateTime' ) {
|
||||||
|
$self->{Sql} .= 'E.StartTime';
|
||||||
} elsif ( $term->{attr} eq 'Date' ) {
|
} elsif ( $term->{attr} eq 'Date' ) {
|
||||||
$self->{Sql} .= "to_days( E.StartTime )";
|
$self->{Sql} .= 'to_days( E.StartTime )';
|
||||||
|
} elsif ( $term->{attr} eq 'StartDate' ) {
|
||||||
|
$self->{Sql} .= 'to_days( E.StartTime )';
|
||||||
} elsif ( $term->{attr} eq 'Time' ) {
|
} elsif ( $term->{attr} eq 'Time' ) {
|
||||||
$self->{Sql} .= "extract( hour_second from E.StartTime )";
|
$self->{Sql} .= "extract( hour_second from E.StartTime )";
|
||||||
} elsif ( $term->{attr} eq 'Weekday' ) {
|
} elsif ( $term->{attr} eq 'Weekday' ) {
|
||||||
$self->{Sql} .= "weekday( E.StartTime )";
|
$self->{Sql} .= "weekday( E.StartTime )";
|
||||||
|
|
||||||
|
# EndTIme options
|
||||||
|
} elsif ( $term->{attr} eq 'EndDateTime' ) {
|
||||||
|
$self->{Sql} .= 'E.EndTime';
|
||||||
|
} elsif ( $term->{attr} eq 'EndDate' ) {
|
||||||
|
$self->{Sql} .= 'to_days( E.EndTime )';
|
||||||
|
} elsif ( $term->{attr} eq 'EndTime' ) {
|
||||||
|
$self->{Sql} .= "extract( hour_second from E.EndTime )";
|
||||||
|
} elsif ( $term->{attr} eq 'EndWeekday' ) {
|
||||||
|
$self->{Sql} .= "weekday( E.EndTime )";
|
||||||
|
|
||||||
|
#
|
||||||
|
} elsif ( $term->{attr} eq 'DiskSpace' ) {
|
||||||
|
$self->{Sql} .= 'E.DiskSpace';
|
||||||
|
$self->{HasDiskPercent} = !undef;
|
||||||
} elsif ( $term->{attr} eq 'DiskPercent' ) {
|
} elsif ( $term->{attr} eq 'DiskPercent' ) {
|
||||||
$self->{Sql} .= "zmDiskPercent";
|
$self->{Sql} .= 'zmDiskPercent';
|
||||||
$self->{HasDiskPercent} = !undef;
|
$self->{HasDiskPercent} = !undef;
|
||||||
} elsif ( $term->{attr} eq 'DiskBlocks' ) {
|
} elsif ( $term->{attr} eq 'DiskBlocks' ) {
|
||||||
$self->{Sql} .= "zmDiskBlocks";
|
$self->{Sql} .= 'zmDiskBlocks';
|
||||||
$self->{HasDiskBlocks} = !undef;
|
$self->{HasDiskBlocks} = !undef;
|
||||||
} elsif ( $term->{attr} eq 'SystemLoad' ) {
|
} elsif ( $term->{attr} eq 'SystemLoad' ) {
|
||||||
$self->{Sql} .= "zmSystemLoad";
|
$self->{Sql} .= 'zmSystemLoad';
|
||||||
$self->{HasSystemLoad} = !undef;
|
$self->{HasSystemLoad} = !undef;
|
||||||
} else {
|
} else {
|
||||||
$self->{Sql} .= "E.".$term->{attr};
|
$self->{Sql} .= 'E.'.$term->{attr};
|
||||||
}
|
}
|
||||||
|
|
||||||
( my $stripped_value = $value ) =~ s/^["\']+?(.+)["\']+?$/$1/;
|
( my $stripped_value = $value ) =~ s/^["\']+?(.+)["\']+?$/$1/;
|
||||||
|
@ -238,16 +259,20 @@ sub Sql {
|
||||||
$self->{Sql} .= " regexp $value";
|
$self->{Sql} .= " regexp $value";
|
||||||
} elsif ( $term->{op} eq '!~' ) {
|
} elsif ( $term->{op} eq '!~' ) {
|
||||||
$self->{Sql} .= " not regexp $value";
|
$self->{Sql} .= " not regexp $value";
|
||||||
|
} elsif ( $term->{op} eq 'IS' ) {
|
||||||
|
$self->{Sql} .= " IS $value";
|
||||||
|
} elsif ( $term->{op} eq 'IS NOT' ) {
|
||||||
|
$self->{Sql} .= " IS NOT $value";
|
||||||
} elsif ( $term->{op} eq '=[]' ) {
|
} elsif ( $term->{op} eq '=[]' ) {
|
||||||
$self->{Sql} .= " in (".join( ",", @value_list ).")";
|
$self->{Sql} .= " in (".join( ",", @value_list ).")";
|
||||||
} elsif ( $term->{op} eq '!~' ) {
|
} elsif ( $term->{op} eq '!~' ) {
|
||||||
$self->{Sql} .= " not in (".join( ",", @value_list ).")";
|
$self->{Sql} .= " not in (".join( ",", @value_list ).")";
|
||||||
} else {
|
} else {
|
||||||
$self->{Sql} .= " ".$term->{op}." $value";
|
$self->{Sql} .= ' '.$term->{op}." $value";
|
||||||
}
|
}
|
||||||
} # end if has an operator
|
} # end if has an operator
|
||||||
if ( exists($term->{cbr}) ) {
|
if ( exists($term->{cbr}) ) {
|
||||||
$self->{Sql} .= " ".str_repeat( ")", $term->{cbr} )." ";
|
$self->{Sql} .= ' '.str_repeat( ")", $term->{cbr} )." ";
|
||||||
}
|
}
|
||||||
} # end foreach term
|
} # end foreach term
|
||||||
} # end if terms
|
} # end if terms
|
||||||
|
@ -256,15 +281,15 @@ sub Sql {
|
||||||
if ( $self->{AutoMessage} ) {
|
if ( $self->{AutoMessage} ) {
|
||||||
# Include all events, including events that are still ongoing
|
# Include all events, including events that are still ongoing
|
||||||
# and have no EndTime yet
|
# and have no EndTime yet
|
||||||
$sql .= " and ( ".$self->{Sql}." )";
|
$sql .= ' AND ( '.$self->{Sql}.' )';
|
||||||
} else {
|
} else {
|
||||||
# Only include closed events (events with valid EndTime)
|
# Only include closed events (events with valid EndTime)
|
||||||
$sql .= " where not isnull(E.EndTime) and ( ".$self->{Sql}." )";
|
$sql .= ' WHERE (E.EndTime IS NOT NULL) AND ( '.$self->{Sql}.' )';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
my @auto_terms;
|
my @auto_terms;
|
||||||
if ( $self->{AutoArchive} ) {
|
if ( $self->{AutoArchive} ) {
|
||||||
push @auto_terms, "E.Archived = 0";
|
push @auto_terms, 'E.Archived = 0';
|
||||||
}
|
}
|
||||||
# Don't do this, it prevents re-generation and concatenation.
|
# Don't do this, it prevents re-generation and concatenation.
|
||||||
# If the file already exists, then the video won't be re-recreated
|
# If the file already exists, then the video won't be re-recreated
|
||||||
|
@ -284,7 +309,7 @@ sub Sql {
|
||||||
push @auto_terms, "E.Executed = 0";
|
push @auto_terms, "E.Executed = 0";
|
||||||
}
|
}
|
||||||
if ( @auto_terms ) {
|
if ( @auto_terms ) {
|
||||||
$sql .= " and ( ".join( " or ", @auto_terms )." )";
|
$sql .= " and ( ".join( ' or ', @auto_terms )." )";
|
||||||
}
|
}
|
||||||
if ( !$filter_expr->{sort_field} ) {
|
if ( !$filter_expr->{sort_field} ) {
|
||||||
$filter_expr->{sort_field} = 'StartTime';
|
$filter_expr->{sort_field} = 'StartTime';
|
||||||
|
@ -292,30 +317,34 @@ sub Sql {
|
||||||
}
|
}
|
||||||
my $sort_column = '';
|
my $sort_column = '';
|
||||||
if ( $filter_expr->{sort_field} eq 'Id' ) {
|
if ( $filter_expr->{sort_field} eq 'Id' ) {
|
||||||
$sort_column = "E.Id";
|
$sort_column = 'E.Id';
|
||||||
} elsif ( $filter_expr->{sort_field} eq 'MonitorName' ) {
|
} elsif ( $filter_expr->{sort_field} eq 'MonitorName' ) {
|
||||||
$sort_column = "M.Name";
|
$sort_column = 'M.Name';
|
||||||
} elsif ( $filter_expr->{sort_field} eq 'Name' ) {
|
} elsif ( $filter_expr->{sort_field} eq 'Name' ) {
|
||||||
$sort_column = "E.Name";
|
$sort_column = 'E.Name';
|
||||||
} elsif ( $filter_expr->{sort_field} eq 'StartTime' ) {
|
} elsif ( $filter_expr->{sort_field} eq 'StartTime' ) {
|
||||||
$sort_column = "E.StartTime";
|
$sort_column = 'E.StartTime';
|
||||||
|
} elsif ( $filter_expr->{sort_field} eq 'EndTime' ) {
|
||||||
|
$sort_column = 'E.EndTime';
|
||||||
} elsif ( $filter_expr->{sort_field} eq 'Secs' ) {
|
} elsif ( $filter_expr->{sort_field} eq 'Secs' ) {
|
||||||
$sort_column = "E.Length";
|
$sort_column = 'E.Length';
|
||||||
} elsif ( $filter_expr->{sort_field} eq 'Frames' ) {
|
} elsif ( $filter_expr->{sort_field} eq 'Frames' ) {
|
||||||
$sort_column = "E.Frames";
|
$sort_column = 'E.Frames';
|
||||||
} elsif ( $filter_expr->{sort_field} eq 'AlarmFrames' ) {
|
} elsif ( $filter_expr->{sort_field} eq 'AlarmFrames' ) {
|
||||||
$sort_column = "E.AlarmFrames";
|
$sort_column = 'E.AlarmFrames';
|
||||||
} elsif ( $filter_expr->{sort_field} eq 'TotScore' ) {
|
} elsif ( $filter_expr->{sort_field} eq 'TotScore' ) {
|
||||||
$sort_column = "E.TotScore";
|
$sort_column = 'E.TotScore';
|
||||||
} elsif ( $filter_expr->{sort_field} eq 'AvgScore' ) {
|
} elsif ( $filter_expr->{sort_field} eq 'AvgScore' ) {
|
||||||
$sort_column = "E.AvgScore";
|
$sort_column = 'E.AvgScore';
|
||||||
} elsif ( $filter_expr->{sort_field} eq 'MaxScore' ) {
|
} elsif ( $filter_expr->{sort_field} eq 'MaxScore' ) {
|
||||||
$sort_column = "E.MaxScore";
|
$sort_column = 'E.MaxScore';
|
||||||
|
} elsif ( $filter_expr->{sort_field} eq 'DiskSpace' ) {
|
||||||
|
$sort_column = 'E.DiskSpace';
|
||||||
} else {
|
} else {
|
||||||
$sort_column = "E.StartTime";
|
$sort_column = 'E.StartTime';
|
||||||
}
|
}
|
||||||
my $sort_order = $filter_expr->{sort_asc}?"asc":"desc";
|
my $sort_order = $filter_expr->{sort_asc}?'asc':'desc';
|
||||||
$sql .= " order by ".$sort_column." ".$sort_order;
|
$sql .= ' order by '.$sort_column." ".$sort_order;
|
||||||
if ( $filter_expr->{limit} ) {
|
if ( $filter_expr->{limit} ) {
|
||||||
$sql .= " limit 0,".$filter_expr->{limit};
|
$sql .= " limit 0,".$filter_expr->{limit};
|
||||||
}
|
}
|
||||||
|
@ -325,7 +354,7 @@ sub Sql {
|
||||||
} # end sub Sql
|
} # end sub Sql
|
||||||
|
|
||||||
sub getDiskPercent {
|
sub getDiskPercent {
|
||||||
my $command = "df " . ($_[0] ? $_[0] : '.');
|
my $command = 'df ' . ($_[0] ? $_[0] : '.');
|
||||||
my $df = qx( $command );
|
my $df = qx( $command );
|
||||||
my $space = -1;
|
my $space = -1;
|
||||||
if ( $df =~ /\s(\d+)%/ms ) {
|
if ( $df =~ /\s(\d+)%/ms ) {
|
||||||
|
@ -335,7 +364,7 @@ sub getDiskPercent {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub getDiskBlocks {
|
sub getDiskBlocks {
|
||||||
my $command = "df .";
|
my $command = 'df .';
|
||||||
my $df = qx( $command );
|
my $df = qx( $command );
|
||||||
my $space = -1;
|
my $space = -1;
|
||||||
if ( $df =~ /\s(\d+)\s+\d+\s+\d+%/ms ) {
|
if ( $df =~ /\s(\d+)\s+\d+\s+\d+%/ms ) {
|
||||||
|
@ -345,7 +374,7 @@ sub getDiskBlocks {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub getLoad {
|
sub getLoad {
|
||||||
my $command = "uptime .";
|
my $command = 'uptime .';
|
||||||
my $uptime = qx( $command );
|
my $uptime = qx( $command );
|
||||||
my $load = -1;
|
my $load = -1;
|
||||||
if ( $uptime =~ /load average:\s+([\d.]+)/ms ) {
|
if ( $uptime =~ /load average:\s+([\d.]+)/ms ) {
|
||||||
|
|
|
@ -678,6 +678,8 @@ sub Dump {
|
||||||
fetch()->logPrint( DEBUG, Data::Dumper->Dump( [ $var ], [ $label ] ) );
|
fetch()->logPrint( DEBUG, Data::Dumper->Dump( [ $var ], [ $label ] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub debug { $_[0]->logPrint( DEBUG, @_ ); }
|
||||||
|
|
||||||
sub Debug( @ ) {
|
sub Debug( @ ) {
|
||||||
fetch()->logPrint( DEBUG, @_ );
|
fetch()->logPrint( DEBUG, @_ );
|
||||||
}
|
}
|
||||||
|
@ -685,14 +687,24 @@ sub Debug( @ ) {
|
||||||
sub Info( @ ) {
|
sub Info( @ ) {
|
||||||
fetch()->logPrint( INFO, @_ );
|
fetch()->logPrint( INFO, @_ );
|
||||||
}
|
}
|
||||||
|
sub info {
|
||||||
|
$_[0]->logPrint( INFO, @_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sub Warning( @ ) {
|
sub Warning( @ ) {
|
||||||
fetch()->logPrint( WARNING, @_ );
|
fetch()->logPrint( WARNING, @_ );
|
||||||
}
|
}
|
||||||
|
sub warn {
|
||||||
|
$_[0]->logPrint( WARNING, @_ );
|
||||||
|
}
|
||||||
|
|
||||||
sub Error( @ ) {
|
sub Error( @ ) {
|
||||||
fetch()->logPrint( ERROR, @_ );
|
fetch()->logPrint( ERROR, @_ );
|
||||||
}
|
}
|
||||||
|
sub error {
|
||||||
|
$_[0]->logPrint( ERROR, @_ );
|
||||||
|
}
|
||||||
|
|
||||||
sub Fatal( @ ) {
|
sub Fatal( @ ) {
|
||||||
fetch()->logPrint( FATAL, @_ );
|
fetch()->logPrint( FATAL, @_ );
|
||||||
|
|
|
@ -42,7 +42,13 @@ use ZoneMinder::Config qw(:all);
|
||||||
use ZoneMinder::Logger qw(:all);
|
use ZoneMinder::Logger qw(:all);
|
||||||
use ZoneMinder::Database qw(:all);
|
use ZoneMinder::Database qw(:all);
|
||||||
|
|
||||||
use vars qw/ $AUTOLOAD /;
|
use vars qw/ $AUTOLOAD $log $dbh/;
|
||||||
|
|
||||||
|
*log = \$ZoneMinder::Logger::logger;
|
||||||
|
*dbh = \$ZoneMinder::Database::dbh;
|
||||||
|
|
||||||
|
my $debug = 1;
|
||||||
|
use constant DEBUG_ALL=>0;
|
||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
my ( $parent, $id, $data ) = @_;
|
my ( $parent, $id, $data ) = @_;
|
||||||
|
@ -110,7 +116,269 @@ sub AUTOLOAD {
|
||||||
return $_[0]{$name};
|
return $_[0]{$name};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub save {
|
||||||
|
my ( $self, $data, $force_insert ) = @_;
|
||||||
|
|
||||||
|
my $type = ref $self;
|
||||||
|
if ( ! $type ) {
|
||||||
|
my ( $caller, undef, $line ) = caller;
|
||||||
|
$log->error("No type in Object::save. self:$self from $caller:$line");
|
||||||
|
}
|
||||||
|
my $local_dbh = eval '$'.$type.'::dbh';
|
||||||
|
$local_dbh = $ZoneMinder::Database::dbh if ! $local_dbh;
|
||||||
|
$self->set( $data ? $data : {} );
|
||||||
|
if ( $debug or DEBUG_ALL ) {
|
||||||
|
if ( $data ) {
|
||||||
|
foreach my $k ( keys %$data ) {
|
||||||
|
$log->debug("Object::save after set $k => $$data{$k} $$self{$k}");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$log->debug("No data after set");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#$debug = 0;
|
||||||
|
|
||||||
|
my $table = eval '$'.$type.'::table';
|
||||||
|
my $fields = eval '\%'.$type.'::fields';
|
||||||
|
my $debug = eval '$'.$type.'::debug';
|
||||||
|
#$debug = DEBUG_ALL if ! $debug;
|
||||||
|
|
||||||
|
my %sql;
|
||||||
|
foreach my $k ( keys %$fields ) {
|
||||||
|
$sql{$$fields{$k}} = $$self{$k} if defined $$fields{$k};
|
||||||
|
} # end foreach
|
||||||
|
if ( ! $force_insert ) {
|
||||||
|
$sql{$$fields{updated_on}} = 'NOW()' if exists $$fields{updated_on};
|
||||||
|
} # end if
|
||||||
|
my $serial = eval '$'.$type.'::serial';
|
||||||
|
my @identified_by = eval '@'.$type.'::identified_by';
|
||||||
|
|
||||||
|
my $ac = ZoneMinder::Database::start_transaction( $local_dbh );
|
||||||
|
if ( ! $serial ) {
|
||||||
|
my $insert = $force_insert;
|
||||||
|
my %serial = eval '%'.$type.'::serial';
|
||||||
|
if ( ! %serial ) {
|
||||||
|
$log->debug("No serial") if $debug;
|
||||||
|
# No serial columns defined, which means that we will do saving by delete/insert instead of insert/update
|
||||||
|
if ( @identified_by ) {
|
||||||
|
my $where = join(' AND ', map { $$fields{$_}.'=?' } @identified_by );
|
||||||
|
if ( $debug ) {
|
||||||
|
$log->debug("DELETE FROM $table WHERE $where");
|
||||||
|
} # end if
|
||||||
|
|
||||||
|
if ( ! ( ( $_ = $local_dbh->prepare("DELETE FROM $table WHERE $where") ) and $_->execute( @$self{@identified_by} ) ) ) {
|
||||||
|
$where =~ s/\?/\%s/g;
|
||||||
|
$log->error("Error deleting: DELETE FROM $table WHERE " . sprintf($where, map { defined $_ ? $_ : 'undef' } ( @$self{@identified_by}) ).'):' . $local_dbh->errstr);
|
||||||
|
$local_dbh->rollback();
|
||||||
|
ZoneMinder::Database::end_transaction( $local_dbh, $ac );
|
||||||
|
return $local_dbh->errstr;
|
||||||
|
} elsif ( $debug ) {
|
||||||
|
$log->debug("SQL succesful DELETE FROM $table WHERE $where");
|
||||||
|
} # end if
|
||||||
|
} # end if
|
||||||
|
$insert = 1;
|
||||||
|
} else {
|
||||||
|
foreach my $id ( @identified_by ) {
|
||||||
|
if ( ! $serial{$id} ) {
|
||||||
|
my ( $caller, undef, $line ) = caller;
|
||||||
|
$log->error("$id nor in serial for $type from $caller:$line") if $debug;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
if ( ! $$self{$id} ) {
|
||||||
|
($$self{$id}) = ($sql{$$fields{$id}}) = $local_dbh->selectrow_array( q{SELECT nextval('} . $serial{$id} . q{')} );
|
||||||
|
$log->debug("SQL statement execution SELECT nextval('$serial{$id}') returned $$self{$id}") if $debug or DEBUG_ALL;
|
||||||
|
$insert = 1;
|
||||||
|
} # end if
|
||||||
|
} # end foreach
|
||||||
|
} # end if ! %serial
|
||||||
|
|
||||||
|
if ( $insert ) {
|
||||||
|
my @keys = keys %sql;
|
||||||
|
my $command = "INSERT INTO $table (" . join(',', @keys ) . ') VALUES (' . join(',', map { '?' } @sql{@keys} ) . ')';
|
||||||
|
if ( ! ( ( $_ = $local_dbh->prepare($command) ) and $_->execute( @sql{@keys} ) ) ) {
|
||||||
|
my $error = $local_dbh->errstr;
|
||||||
|
$command =~ s/\?/\%s/g;
|
||||||
|
$log->error('SQL statement execution failed: ('.sprintf($command, , map { defined $_ ? $_ : 'undef' } ( @sql{@keys}) ).'):' . $local_dbh->errstr);
|
||||||
|
$local_dbh->rollback();
|
||||||
|
ZoneMinder::Database::end_transaction( $local_dbh, $ac );
|
||||||
|
return $error;
|
||||||
|
} # end if
|
||||||
|
if ( $debug or DEBUG_ALL ) {
|
||||||
|
$command =~ s/\?/\%s/g;
|
||||||
|
$log->debug('SQL statement execution: ('.sprintf($command, , map { defined $_ ? $_ : 'undef' } ( @sql{@keys} ) ).'):' );
|
||||||
|
} # end if
|
||||||
|
} else {
|
||||||
|
my @keys = keys %sql;
|
||||||
|
my $command = "UPDATE $table SET " . join(',', map { $_ . ' = ?' } @keys ) . ' WHERE ' . join(' AND ', map { $_ . ' = ?' } @$fields{@identified_by} );
|
||||||
|
if ( ! ( $_ = $local_dbh->prepare($command) and $_->execute( @sql{@keys,@$fields{@identified_by}} ) ) ) {
|
||||||
|
my $error = $local_dbh->errstr;
|
||||||
|
$command =~ s/\?/\%s/g;
|
||||||
|
$log->error('SQL failed: ('.sprintf($command, , map { defined $_ ? $_ : 'undef' } ( @sql{@keys, @$fields{@identified_by}}) ).'):' . $local_dbh->errstr);
|
||||||
|
$local_dbh->rollback();
|
||||||
|
ZoneMinder::Database::end_transaction( $local_dbh, $ac );
|
||||||
|
return $error;
|
||||||
|
} # end if
|
||||||
|
if ( $debug or DEBUG_ALL ) {
|
||||||
|
$command =~ s/\?/\%s/g;
|
||||||
|
$log->debug('SQL DEBUG: ('.sprintf($command, map { defined $_ ? $_ : 'undef' } ( @sql{@keys,@$fields{@identified_by}} ) ).'):' );
|
||||||
|
} # end if
|
||||||
|
} # end if
|
||||||
|
} else { # not identified_by
|
||||||
|
@identified_by = ('id') if ! @identified_by;
|
||||||
|
my $need_serial = ! ( @identified_by == map { $$self{$_} ? $_ : () } @identified_by );
|
||||||
|
|
||||||
|
if ( $force_insert or $need_serial ) {
|
||||||
|
|
||||||
|
if ( $need_serial ) {
|
||||||
|
if ( $serial ) {
|
||||||
|
@$self{@identified_by} = @sql{@$fields{@identified_by}} = $local_dbh->selectrow_array( q{SELECT nextval('} . $serial . q{')} );
|
||||||
|
if ( $local_dbh->errstr() ) {
|
||||||
|
$log->error("Error getting next id. " . $local_dbh->errstr() );
|
||||||
|
$log->error("SQL statement execution SELECT nextval('$serial') returned ".join(',',@$self{@identified_by}));
|
||||||
|
} elsif ( $debug or DEBUG_ALL ) {
|
||||||
|
$log->debug("SQL statement execution SELECT nextval('$serial') returned ".join(',',@$self{@identified_by}));
|
||||||
|
} # end if
|
||||||
|
} # end if
|
||||||
|
} # end if
|
||||||
|
my @keys = keys %sql;
|
||||||
|
my $command = "INSERT INTO $table (" . join(',', @keys ) . ') VALUES (' . join(',', map { '?' } @sql{@keys} ) . ')';
|
||||||
|
if ( ! ( $_ = $local_dbh->prepare($command) and $_->execute( @sql{@keys} ) ) ) {
|
||||||
|
$command =~ s/\?/\%s/g;
|
||||||
|
my $error = $local_dbh->errstr;
|
||||||
|
$log->error('SQL failed: ('.sprintf($command, map { defined $_ ? $_ : 'undef' } ( @sql{@keys}) ).'):' . $error);
|
||||||
|
$local_dbh->rollback();
|
||||||
|
ZoneMinder::Database::end_transaction( $local_dbh, $ac );
|
||||||
|
return $error;
|
||||||
|
} # end if
|
||||||
|
if ( $debug or DEBUG_ALL ) {
|
||||||
|
$command =~ s/\?/\%s/g;
|
||||||
|
$log->debug('SQL DEBUG: ('.sprintf($command, map { defined $_ ? $_ : 'undef' } ( @sql{@keys} ) ).'):' );
|
||||||
|
} # end if
|
||||||
|
} else {
|
||||||
|
delete $sql{created_on};
|
||||||
|
my @keys = keys %sql;
|
||||||
|
@keys = sets::exclude( [ @$fields{@identified_by} ], \@keys );
|
||||||
|
my $command = "UPDATE $table SET " . join(',', map { $_ . ' = ?' } @keys ) . ' WHERE ' . join(' AND ', map { $$fields{$_} .'= ?' } @identified_by );
|
||||||
|
if ( ! ( $_ = $local_dbh->prepare($command) and $_->execute( @sql{@keys}, @sql{@$fields{@identified_by}} ) ) ) {
|
||||||
|
my $error = $local_dbh->errstr;
|
||||||
|
$command =~ s/\?/\%s/g;
|
||||||
|
$log->error('SQL failed: ('.sprintf($command, map { defined $_ ? $_ : 'undef' } ( @sql{@keys}, @sql{@$fields{@identified_by}} ) ).'):' . $error) if $log;
|
||||||
|
$local_dbh->rollback();
|
||||||
|
ZoneMinder::Database::end_transaction( $local_dbh, $ac );
|
||||||
|
return $error;
|
||||||
|
} # end if
|
||||||
|
if ( $debug or DEBUG_ALL ) {
|
||||||
|
$command =~ s/\?/\%s/g;
|
||||||
|
$log->debug('SQL DEBUG: ('.sprintf($command, map { defined $_ ? ( ref $_ eq 'ARRAY' ? join(',',@{$_}) : $_ ) : 'undef' } ( @sql{@keys}, @$self{@identified_by} ) ).'):' );
|
||||||
|
} # end if
|
||||||
|
} # end if
|
||||||
|
} # end if
|
||||||
|
ZoneMinder::Database::end_transaction( $local_dbh, $ac );
|
||||||
|
$self->load();
|
||||||
|
#if ( $$fields{id} ) {
|
||||||
|
#if ( ! $ZoneMinder::Object::cache{$type}{$$self{id}} ) {
|
||||||
|
#$ZoneMinder::Object::cache{$type}{$$self{id}} = $self;
|
||||||
|
#} # end if
|
||||||
|
#delete $ZoneMinder::Object::cache{$config{db_name}}{$type}{$$self{id}};
|
||||||
|
#} # end if
|
||||||
|
#$log->debug("after delete");
|
||||||
|
#eval 'if ( %'.$type.'::find_cache ) { %'.$type.'::find_cache = (); }';
|
||||||
|
#$log->debug("after clear cache");
|
||||||
|
return '';
|
||||||
|
} # end sub save
|
||||||
|
|
||||||
|
sub set {
|
||||||
|
my ( $self, $params ) = @_;
|
||||||
|
my @set_fields = ();
|
||||||
|
|
||||||
|
my $type = ref $self;
|
||||||
|
my %fields = eval ('%'.$type.'::fields');
|
||||||
|
if ( ! %fields ) {
|
||||||
|
$log->warn('ZoneMinder::Object::set called on an object with no fields');
|
||||||
|
} # end if
|
||||||
|
my %defaults = eval('%'.$type.'::defaults');
|
||||||
|
if ( ref $params ne 'HASH' ) {
|
||||||
|
my ( $caller, undef, $line ) = caller;
|
||||||
|
$openprint::log->error("$type -> set called with non-hash params from $caller $line");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach my $field ( keys %fields ) {
|
||||||
|
$log->debug("field: $field, param: ".$$params{$field}) if $debug;
|
||||||
|
if ( exists $$params{$field} ) {
|
||||||
|
$openprint::log->debug("field: $field, $$self{$field} =? param: ".$$params{$field}) if $debug;
|
||||||
|
if ( ( ! defined $$self{$field} ) or ($$self{$field} ne $params->{$field}) ) {
|
||||||
|
# Only make changes to fields that have changed
|
||||||
|
if ( defined $fields{$field} ) {
|
||||||
|
$$self{$field} = $$params{$field} if defined $fields{$field};
|
||||||
|
push @set_fields, $fields{$field}, $$params{$field}; #mark for sql updating
|
||||||
|
} # end if
|
||||||
|
$openprint::log->debug("Running $field with $$params{$field}") if $debug;
|
||||||
|
if ( my $func = $self->can( $field ) ) {
|
||||||
|
$func->( $self, $$params{$field} );
|
||||||
|
} # end if
|
||||||
|
} # end if
|
||||||
|
} # end if
|
||||||
|
|
||||||
|
if ( defined $fields{$field} ) {
|
||||||
|
if ( $$self{$field} ) {
|
||||||
|
$$self{$field} = transform( $type, $field, $$self{$field} );
|
||||||
|
} # end if $$self{field}
|
||||||
|
}
|
||||||
|
} # end foreach field
|
||||||
|
|
||||||
|
foreach my $field ( keys %defaults ) {
|
||||||
|
|
||||||
|
if ( ( ! exists $$self{$field} ) or (!defined $$self{$field}) or ( $$self{$field} eq '' ) ) {
|
||||||
|
$log->debug("Setting default ($field) ($$self{$field}) ($defaults{$field}) ") if $debug;
|
||||||
|
if ( defined $defaults{$field} ) {
|
||||||
|
$log->debug("Default $field is defined: $defaults{$field}") if $debug;
|
||||||
|
if ( $defaults{$field} eq 'NOW()' ) {
|
||||||
|
$$self{$field} = 'NOW()';
|
||||||
|
} else {
|
||||||
|
$$self{$field} = eval($defaults{$field});
|
||||||
|
$log->error( "Eval error of object default $field default ($defaults{$field}) Reason: " . $@ ) if $@;
|
||||||
|
} # end if
|
||||||
|
} else {
|
||||||
|
$$self{$field} = $defaults{$field};
|
||||||
|
} # end if
|
||||||
|
#$$self{$field} = ( defined $defaults{$field} ) ? eval($defaults{$field}) : $defaults{$field};
|
||||||
|
$log->debug("Setting default for ($field) using ($defaults{$field}) to ($$self{$field}) ") if $debug;
|
||||||
|
} # end if
|
||||||
|
} # end foreach default
|
||||||
|
return @set_fields;
|
||||||
|
} # end sub set
|
||||||
|
|
||||||
|
sub transform {
|
||||||
|
my $type = ref $_[0];
|
||||||
|
$type = $_[0] if ! $type;
|
||||||
|
my $fields = eval '\%'.$type.'::fields';
|
||||||
|
my $value = $_[2];
|
||||||
|
|
||||||
|
if ( defined $$fields{$_[1]} ) {
|
||||||
|
my @transforms = eval('@{$'.$type.'::transforms{$_[1]}}');
|
||||||
|
$openprint::log->debug("Transforms for $_[1] before $_[2]: @transforms") if $debug;
|
||||||
|
if ( @transforms ) {
|
||||||
|
foreach my $transform ( @transforms ) {
|
||||||
|
if ( $transform =~ /^s\// or $transform =~ /^tr\// ) {
|
||||||
|
eval '$value =~ ' . $transform;
|
||||||
|
} elsif ( $transform =~ /^<(\d+)/ ) {
|
||||||
|
if ( $value > $1 ) {
|
||||||
|
$value = undef;
|
||||||
|
} # end if
|
||||||
|
} else {
|
||||||
|
$openprint::log->debug("evalling $value ".$transform . " Now value is $value" );
|
||||||
|
eval '$value '.$transform;
|
||||||
|
$openprint::log->error("Eval error $@") if $@;
|
||||||
|
}
|
||||||
|
$openprint::log->debug("After $transform: $value") if $debug;
|
||||||
|
} # end foreach
|
||||||
|
} # end if
|
||||||
|
} else {
|
||||||
|
$openprint::log->error("Object::transform ($_[1]) not in fields for $type");
|
||||||
|
} # end if
|
||||||
|
return $value;
|
||||||
|
|
||||||
|
} # end sub transform
|
||||||
1;
|
1;
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
|
|
|
@ -246,7 +246,7 @@ MAIN: while( $loop ) {
|
||||||
$$Event{Path} = join('/', $Storage->Path(), $day_dir,$event_path);
|
$$Event{Path} = join('/', $Storage->Path(), $day_dir,$event_path);
|
||||||
$Event->MonitorId( $monitor_dir );
|
$Event->MonitorId( $monitor_dir );
|
||||||
$Event->StorageId( $Storage->Id() );
|
$Event->StorageId( $Storage->Id() );
|
||||||
$Event->DiskUsage( undef );
|
$Event->DiskSpace( undef );
|
||||||
} # event path exists
|
} # event path exists
|
||||||
} # end foreach event_link
|
} # end foreach event_link
|
||||||
chdir( $Storage->Path() );
|
chdir( $Storage->Path() );
|
||||||
|
|
|
@ -55,7 +55,7 @@ use bytes;
|
||||||
# ==========================================================================
|
# ==========================================================================
|
||||||
|
|
||||||
# in useconds, not seconds.
|
# in useconds, not seconds.
|
||||||
use constant MAX_CONNECT_DELAY => 10*1000*1000;
|
use constant MAX_CONNECT_DELAY => 40;
|
||||||
|
|
||||||
# ==========================================================================
|
# ==========================================================================
|
||||||
#
|
#
|
||||||
|
@ -69,6 +69,9 @@ use POSIX;
|
||||||
use Socket;
|
use Socket;
|
||||||
use IO::Handle;
|
use IO::Handle;
|
||||||
use Time::HiRes qw(usleep);
|
use Time::HiRes qw(usleep);
|
||||||
|
use Sys::MemInfo qw(totalmem freemem totalswap freeswap);
|
||||||
|
use Sys::CpuLoad;
|
||||||
|
|
||||||
use autouse 'Pod::Usage'=>qw(pod2usage);
|
use autouse 'Pod::Usage'=>qw(pod2usage);
|
||||||
#use Data::Dumper;
|
#use Data::Dumper;
|
||||||
|
|
||||||
|
@ -140,11 +143,19 @@ foreach my $arg ( @ARGV ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $dbh = zmDbConnect();
|
||||||
|
|
||||||
socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" );
|
socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" );
|
||||||
|
|
||||||
my $saddr = sockaddr_un( SOCK_FILE );
|
my $saddr = sockaddr_un( SOCK_FILE );
|
||||||
my $server_up = connect( CLIENT, $saddr );
|
my $server_up = connect( CLIENT, $saddr );
|
||||||
if ( ! $server_up ) {
|
if ( ! $server_up ) {
|
||||||
|
if ( $Config{ZM_SERVER_ID} ) {
|
||||||
|
if ( ! defined $dbh->do(q{UPDATE Servers SET Status=?,TotalMem=?,FreeMem=?,TotalSwap=?,FreeSwap=? WHERE Id=?}, undef,
|
||||||
|
'NotRunning', &totalmem, &freemem, &totalswap, &freeswap, $Config{ZM_SERVER_ID} ) ) {
|
||||||
|
Error("Failed Updating status of Server record to Not RUnning for Id=$Config{ZM_SERVER_ID}" . $dbh->errstr());
|
||||||
|
}
|
||||||
|
}
|
||||||
# Server is not up. Some commands can still be handled
|
# Server is not up. Some commands can still be handled
|
||||||
if ( $command eq 'logrot' ) {
|
if ( $command eq 'logrot' ) {
|
||||||
# If server is not running, then logrotate doesn't need to do anything.
|
# If server is not running, then logrotate doesn't need to do anything.
|
||||||
|
@ -172,7 +183,7 @@ if ( ! $server_up ) {
|
||||||
my $attempts = 0;
|
my $attempts = 0;
|
||||||
while( !connect( CLIENT, $saddr ) ) {
|
while( !connect( CLIENT, $saddr ) ) {
|
||||||
$attempts++;
|
$attempts++;
|
||||||
Error("Waiting for zmdc.pl server process, attempt $attempts" );
|
Error("Waiting for zmdc.pl server process at " . SOCK_FILE.", attempt $attempts" );
|
||||||
Fatal( "Can't connect: $!" ) if ($attempts > MAX_CONNECT_DELAY);
|
Fatal( "Can't connect: $!" ) if ($attempts > MAX_CONNECT_DELAY);
|
||||||
usleep(200000);
|
usleep(200000);
|
||||||
} # end while
|
} # end while
|
||||||
|
@ -219,6 +230,8 @@ use POSIX;
|
||||||
use Socket;
|
use Socket;
|
||||||
use IO::Handle;
|
use IO::Handle;
|
||||||
use Time::HiRes qw(usleep);
|
use Time::HiRes qw(usleep);
|
||||||
|
use Sys::MemInfo qw(totalmem freemem totalswap freeswap);
|
||||||
|
use Sys::CpuLoad;
|
||||||
#use Data::Dumper;
|
#use Data::Dumper;
|
||||||
|
|
||||||
use constant KILL_DELAY => 100*1000; # 1/10th of a second
|
use constant KILL_DELAY => 100*1000; # 1/10th of a second
|
||||||
|
@ -250,8 +263,10 @@ sub run {
|
||||||
|
|
||||||
killAll( 1 );
|
killAll( 1 );
|
||||||
|
|
||||||
|
dPrint( ZoneMinder::Logger::INFO, 'Socket should be open at ' .main::SOCK_FILE );
|
||||||
|
my $dbh = zmDbConnect(1);
|
||||||
socket( SERVER, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" );
|
socket( SERVER, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" );
|
||||||
unlink( main::SOCK_FILE ) or Error( 'Unable to unlink ' . main::SOCK_FILE .". Error message was: $!" ) if ( -e main::SOCK_FILE );
|
unlink( main::SOCK_FILE ) or Error( 'Unable to unlink ' . main::SOCK_FILE .". Error message was: $!" ) if -e main::SOCK_FILE;
|
||||||
bind( SERVER, $saddr ) or Fatal( "Can't bind to " . main::SOCK_FILE . ": $!" );
|
bind( SERVER, $saddr ) or Fatal( "Can't bind to " . main::SOCK_FILE . ": $!" );
|
||||||
listen( SERVER, SOMAXCONN ) or Fatal( "Can't listen: $!" );
|
listen( SERVER, SOMAXCONN ) or Fatal( "Can't listen: $!" );
|
||||||
|
|
||||||
|
@ -265,8 +280,16 @@ sub run {
|
||||||
vec( $rin, fileno(SERVER), 1 ) = 1;
|
vec( $rin, fileno(SERVER), 1 ) = 1;
|
||||||
my $win = $rin;
|
my $win = $rin;
|
||||||
my $ein = $win;
|
my $ein = $win;
|
||||||
my $timeout = 0.1;
|
my $timeout = 1;
|
||||||
while( 1 ) {
|
while( 1 ) {
|
||||||
|
if ( $Config{ZM_SERVER_ID} ) {
|
||||||
|
$dbh = zmDbConnect() if ! $dbh->ping();
|
||||||
|
my @cpuload = Sys::CpuLoad::load();
|
||||||
|
if ( ! defined $dbh->do(q{UPDATE Servers SET Status=?,CpuLoad=?,TotalMem=?,FreeMem=?,TotalSwap=?,FreeSwap=? WHERE Id=?}, undef,
|
||||||
|
'Running', $cpuload[0], &totalmem, &freemem, &totalswap, &freeswap, $Config{ZM_SERVER_ID} ) ) {
|
||||||
|
Error("Failed Updating status of Server record for Id=$Config{ZM_SERVER_ID}".$dbh->errstr());
|
||||||
|
}
|
||||||
|
}
|
||||||
my $nfound = select( my $rout = $rin, undef, undef, $timeout );
|
my $nfound = select( my $rout = $rin, undef, undef, $timeout );
|
||||||
if ( $nfound > 0 ) {
|
if ( $nfound > 0 ) {
|
||||||
if ( vec( $rout, fileno(SERVER), 1 ) ) {
|
if ( vec( $rout, fileno(SERVER), 1 ) ) {
|
||||||
|
@ -327,6 +350,12 @@ sub run {
|
||||||
.strftime( '%y/%m/%d %H:%M:%S', localtime() )
|
.strftime( '%y/%m/%d %H:%M:%S', localtime() )
|
||||||
."\n"
|
."\n"
|
||||||
);
|
);
|
||||||
|
if ( $Config{ZM_SERVER_ID} ) {
|
||||||
|
$dbh = zmDbConnect() if ! $dbh->ping();
|
||||||
|
if ( ! defined $dbh->do(q{UPDATE Servers SET Status='NotRunning' WHERE Id=?}, undef, $Config{ZM_SERVER_ID} ) ) {
|
||||||
|
Error("Failed Updating status of Server record for Id=$Config{ZM_SERVER_ID}".$dbh->errstr());
|
||||||
|
}
|
||||||
|
}
|
||||||
unlink( main::SOCK_FILE ) or Error( 'Unable to unlink ' . main::SOCK_FILE .". Error message was: $!" ) if ( -e main::SOCK_FILE );
|
unlink( main::SOCK_FILE ) or Error( 'Unable to unlink ' . main::SOCK_FILE .". Error message was: $!" ) if ( -e main::SOCK_FILE );
|
||||||
unlink( ZM_PID ) or Error( 'Unable to unlink ' . ZM_PID .". Error message was: $!" ) if ( -e ZM_PID );
|
unlink( ZM_PID ) or Error( 'Unable to unlink ' . ZM_PID .". Error message was: $!" ) if ( -e ZM_PID );
|
||||||
exit();
|
exit();
|
||||||
|
@ -393,7 +422,7 @@ sub start {
|
||||||
sigprocmask( SIG_SETMASK, $sigset ) or Fatal( "Can't restore SIGCHLD: $!" );
|
sigprocmask( SIG_SETMASK, $sigset ) or Fatal( "Can't restore SIGCHLD: $!" );
|
||||||
} elsif ( defined($cpid ) ) {
|
} elsif ( defined($cpid ) ) {
|
||||||
# Force reconnection to the db.
|
# Force reconnection to the db.
|
||||||
zmDbConnect(1);
|
$dbh = zmDbConnect(1);
|
||||||
logReinit();
|
logReinit();
|
||||||
|
|
||||||
dPrint( ZoneMinder::Logger::INFO, "'".join( ' ', ( $daemon, @args ) )
|
dPrint( ZoneMinder::Logger::INFO, "'".join( ' ', ( $daemon, @args ) )
|
||||||
|
|
|
@ -214,6 +214,7 @@ sub getFilters {
|
||||||
or AutoMessage = 1
|
or AutoMessage = 1
|
||||||
or AutoExecute = 1
|
or AutoExecute = 1
|
||||||
or AutoDelete = 1
|
or AutoDelete = 1
|
||||||
|
or UpdateDiskSpace = 1
|
||||||
) ORDER BY Name';
|
) ORDER BY Name';
|
||||||
my $sth = $dbh->prepare_cached( $sql )
|
my $sth = $dbh->prepare_cached( $sql )
|
||||||
or Fatal( "Unable toprepare '$sql': ".$dbh->errstr() );
|
or Fatal( "Unable toprepare '$sql': ".$dbh->errstr() );
|
||||||
|
@ -250,14 +251,20 @@ sub checkFilter {
|
||||||
my $filter = shift;
|
my $filter = shift;
|
||||||
|
|
||||||
my @Events = $filter->Execute();
|
my @Events = $filter->Execute();
|
||||||
Info( join( "Checking filter '$filter->{Name}'",
|
Info(
|
||||||
($filter->{AutoDelete}?', delete':''),
|
join(' ',
|
||||||
($filter->{AutoArchive}?', archive':''),
|
'Checking filter', $filter->{Name},
|
||||||
($filter->{AutoVideo}?', video':''),
|
join( ', ',
|
||||||
($filter->{AutoUpload}?', upload':''),
|
|
||||||
($filter->{AutoEmail}?', email':''),
|
($filter->{AutoDelete}?'delete':()),
|
||||||
($filter->{AutoMessage}?', message':''),
|
($filter->{AutoArchive}?'archive':()),
|
||||||
($filter->{AutoExecute}?', execute':''),
|
($filter->{AutoVideo}?'video':()),
|
||||||
|
($filter->{AutoUpload}?'upload':()),
|
||||||
|
($filter->{AutoEmail}?'email':()),
|
||||||
|
($filter->{AutoMessage}?'message':()),
|
||||||
|
($filter->{AutoExecute}?'execute':()),
|
||||||
|
($filter->{UpdateDiskSpace}?'update disk space':()),
|
||||||
|
),
|
||||||
'returned' , scalar @Events , 'events',
|
'returned' , scalar @Events , 'events',
|
||||||
"\n",
|
"\n",
|
||||||
) );
|
) );
|
||||||
|
@ -308,6 +315,12 @@ sub checkFilter {
|
||||||
Error( "Unable toto delete event $event->{Id} as previous operations failed\n" );
|
Error( "Unable toto delete event $event->{Id} as previous operations failed\n" );
|
||||||
}
|
}
|
||||||
} # end if AutoDelete
|
} # end if AutoDelete
|
||||||
|
if ( $filter->{UpdateDiskSpace} ) {
|
||||||
|
my $Event = new ZoneMinder::Event( $$event{Id}, $event );
|
||||||
|
$Event->DiskSpace(undef);
|
||||||
|
$Event->save();
|
||||||
|
|
||||||
|
} # end if UpdateDiskSpace
|
||||||
} # end foreach event
|
} # end foreach event
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -419,8 +419,8 @@ void Event::AddFramesInternal( int n_frames, int start_frame, Image **images, st
|
||||||
strncpy( sql, "insert into Frames ( EventId, FrameId, TimeStamp, Delta ) values ", sizeof(sql) );
|
strncpy( sql, "insert into Frames ( EventId, FrameId, TimeStamp, Delta ) values ", sizeof(sql) );
|
||||||
int frameCount = 0;
|
int frameCount = 0;
|
||||||
for ( int i = start_frame; i < n_frames && i - start_frame < ZM_SQL_BATCH_SIZE; i++ ) {
|
for ( int i = start_frame; i < n_frames && i - start_frame < ZM_SQL_BATCH_SIZE; i++ ) {
|
||||||
if ( !timestamps[i]->tv_sec ) {
|
if ( timestamps[i]->tv_sec <= 0 ) {
|
||||||
Debug( 1, "Not adding pre-capture frame %d, zero timestamp", i );
|
Debug( 1, "Not adding pre-capture frame %d, zero or less than 0 timestamp", i );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -271,8 +271,7 @@ void EventStream::processCommand( const CmdMsg *msg ) {
|
||||||
case CMD_VARPLAY :
|
case CMD_VARPLAY :
|
||||||
{
|
{
|
||||||
Debug( 1, "Got VARPLAY command" );
|
Debug( 1, "Got VARPLAY command" );
|
||||||
if ( paused )
|
if ( paused ) {
|
||||||
{
|
|
||||||
// Clear paused flag
|
// Clear paused flag
|
||||||
paused = false;
|
paused = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1180,6 +1180,11 @@ bool Monitor::Analyse() {
|
||||||
if ( image_count && fps_report_interval && !(image_count%fps_report_interval) ) {
|
if ( image_count && fps_report_interval && !(image_count%fps_report_interval) ) {
|
||||||
fps = double(fps_report_interval)/(now.tv_sec-last_fps_time);
|
fps = double(fps_report_interval)/(now.tv_sec-last_fps_time);
|
||||||
Info( "%s: %d - Analysing at %.2f fps", name, image_count, fps );
|
Info( "%s: %d - Analysing at %.2f fps", name, image_count, fps );
|
||||||
|
static char sql[ZM_SQL_SML_BUFSIZ];
|
||||||
|
snprintf( sql, sizeof(sql), "UPDATE Monitors SET AnalysisFPS = '%.2lf' WHERE Id = '%d'", fps, id );
|
||||||
|
if ( mysql_query( &dbconn, sql ) ) {
|
||||||
|
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
||||||
|
}
|
||||||
last_fps_time = now.tv_sec;
|
last_fps_time = now.tv_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1678,7 +1683,7 @@ void Monitor::Reload() {
|
||||||
|
|
||||||
static char sql[ZM_SQL_MED_BUFSIZ];
|
static char sql[ZM_SQL_MED_BUFSIZ];
|
||||||
// This seems to have fallen out of date.
|
// This seems to have fallen out of date.
|
||||||
snprintf( sql, sizeof(sql), "select Function+0, Enabled, LinkedMonitors, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, WarmupCount, PreEventCount, PostEventCount, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = '%d'", id );
|
snprintf( sql, sizeof(sql), "select Function+0, Enabled, LinkedMonitors, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, WarmupCount, PreEventCount, PostEventCount, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = '%d'", id );
|
||||||
|
|
||||||
if ( mysql_query( &dbconn, sql ) ) {
|
if ( mysql_query( &dbconn, sql ) ) {
|
||||||
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
||||||
|
@ -1843,7 +1848,7 @@ void Monitor::ReloadLinkedMonitors( const char *p_linked_monitors ) {
|
||||||
|
|
||||||
#if ZM_HAS_V4L
|
#if ZM_HAS_V4L
|
||||||
int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose purpose ) {
|
int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose purpose ) {
|
||||||
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Function != 'None' and Type = 'Local'";
|
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Function != 'None' and Type = 'Local'";
|
||||||
;
|
;
|
||||||
if ( device[0] ) {
|
if ( device[0] ) {
|
||||||
sql += " AND Device='";
|
sql += " AND Device='";
|
||||||
|
@ -2032,7 +2037,7 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose
|
||||||
#endif // ZM_HAS_V4L
|
#endif // ZM_HAS_V4L
|
||||||
|
|
||||||
int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const char *port, const char *path, Monitor **&monitors, Purpose purpose ) {
|
int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const char *port, const char *path, Monitor **&monitors, Purpose purpose ) {
|
||||||
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Remote'";
|
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Remote'";
|
||||||
if ( staticConfig.SERVER_ID ) {
|
if ( staticConfig.SERVER_ID ) {
|
||||||
sql += stringtf( " AND ServerId=%d", staticConfig.SERVER_ID );
|
sql += stringtf( " AND ServerId=%d", staticConfig.SERVER_ID );
|
||||||
}
|
}
|
||||||
|
@ -2215,7 +2220,7 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c
|
||||||
}
|
}
|
||||||
|
|
||||||
int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose purpose ) {
|
int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose purpose ) {
|
||||||
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'File'";
|
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'File'";
|
||||||
if ( file[0] ) {
|
if ( file[0] ) {
|
||||||
sql += " AND Path='";
|
sql += " AND Path='";
|
||||||
sql += file;
|
sql += file;
|
||||||
|
@ -2365,7 +2370,7 @@ int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose pu
|
||||||
|
|
||||||
#if HAVE_LIBAVFORMAT
|
#if HAVE_LIBAVFORMAT
|
||||||
int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose purpose ) {
|
int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose purpose ) {
|
||||||
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Path, Method, Options, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Ffmpeg'";
|
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Path, Method, Options, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Ffmpeg'";
|
||||||
if ( file[0] ) {
|
if ( file[0] ) {
|
||||||
sql += " AND Path = '";
|
sql += " AND Path = '";
|
||||||
sql += file;
|
sql += file;
|
||||||
|
@ -2525,7 +2530,7 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose
|
||||||
#endif // HAVE_LIBAVFORMAT
|
#endif // HAVE_LIBAVFORMAT
|
||||||
|
|
||||||
Monitor *Monitor::Load( unsigned int p_id, bool load_zones, Purpose purpose ) {
|
Monitor *Monitor::Load( unsigned int p_id, bool load_zones, Purpose purpose ) {
|
||||||
std::string sql = stringtf( "select Id, Name, ServerId, StorageId, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Protocol, Method, Host, Port, Path, Options, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Id = %d", p_id );
|
std::string sql = stringtf( "select Id, Name, ServerId, StorageId, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Protocol, Method, Host, Port, Path, Options, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Id = %d", p_id );
|
||||||
|
|
||||||
zmDbRow dbrow;
|
zmDbRow dbrow;
|
||||||
if ( ! dbrow.fetch( sql.c_str() ) ) {
|
if ( ! dbrow.fetch( sql.c_str() ) ) {
|
||||||
|
@ -2981,6 +2986,11 @@ int Monitor::Capture() {
|
||||||
//Info( "%d -> %d -> %lf -> %lf", now-last_fps_time, fps_report_interval/(now-last_fps_time), double(fps_report_interval)/(now-last_fps_time), fps );
|
//Info( "%d -> %d -> %lf -> %lf", now-last_fps_time, fps_report_interval/(now-last_fps_time), double(fps_report_interval)/(now-last_fps_time), fps );
|
||||||
Info( "%s: %d - Capturing at %.2lf fps", name, image_count, fps );
|
Info( "%s: %d - Capturing at %.2lf fps", name, image_count, fps );
|
||||||
last_fps_time = now;
|
last_fps_time = now;
|
||||||
|
static char sql[ZM_SQL_SML_BUFSIZ];
|
||||||
|
snprintf( sql, sizeof(sql), "UPDATE Monitors SET CaptureFPS = '%.2lf' WHERE Id = '%d'", fps, id );
|
||||||
|
if ( mysql_query( &dbconn, sql ) ) {
|
||||||
|
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Icon: I'm not sure these should be here. They have nothing to do with capturing
|
// Icon: I'm not sure these should be here. They have nothing to do with capturing
|
||||||
|
|
|
@ -553,7 +553,7 @@ void MonitorStream::runStream() {
|
||||||
Debug( 2, "Assigned temporary buffer" );
|
Debug( 2, "Assigned temporary buffer" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // end if connkey & playback_buffer
|
||||||
|
|
||||||
float max_secs_since_last_sent_frame = 10.0; //should be > keep alive amount (5 secs)
|
float max_secs_since_last_sent_frame = 10.0; //should be > keep alive amount (5 secs)
|
||||||
while ( !zm_terminate ) {
|
while ( !zm_terminate ) {
|
||||||
|
|
|
@ -44,7 +44,11 @@ bool StreamBase::loadMonitor( int monitor_id ) {
|
||||||
Fatal( "Unable to load monitor id %d for streaming", monitor_id );
|
Fatal( "Unable to load monitor id %d for streaming", monitor_id );
|
||||||
return( false );
|
return( false );
|
||||||
}
|
}
|
||||||
monitor->connect();
|
if ( ! monitor->connect() ) {
|
||||||
|
Fatal( "Unable to connect to monitor id %d for streaming", monitor_id );
|
||||||
|
return( false );
|
||||||
|
}
|
||||||
|
|
||||||
return( true );
|
return( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -221,6 +221,13 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Info("Starting Capture version %s", ZM_VERSION);
|
Info("Starting Capture version %s", ZM_VERSION);
|
||||||
|
static char sql[ZM_SQL_SML_BUFSIZ];
|
||||||
|
for ( int i = 0; i < n_monitors; i ++ ) {
|
||||||
|
snprintf( sql, sizeof(sql), "UPDATE Monitors SET Status = 'Running' WHERE Id = '%d'", monitors[i]->Id() );
|
||||||
|
if ( mysql_query( &dbconn, sql ) ) {
|
||||||
|
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
zmSetDefaultTermHandler();
|
zmSetDefaultTermHandler();
|
||||||
zmSetDefaultDieHandler();
|
zmSetDefaultDieHandler();
|
||||||
|
|
|
@ -108,6 +108,7 @@ $statusData = array(
|
||||||
"elements" => array(
|
"elements" => array(
|
||||||
"Id" => array( "sql" => "Events.Id" ),
|
"Id" => array( "sql" => "Events.Id" ),
|
||||||
"MonitorId" => true,
|
"MonitorId" => true,
|
||||||
|
"MonitorName" => array("sql" => "(SELECT Monitors.Name FROM Monitors WHERE Monitors.Id = Events.MonitorId)"),
|
||||||
"Name" => true,
|
"Name" => true,
|
||||||
"Cause" => true,
|
"Cause" => true,
|
||||||
"StartTime" => true,
|
"StartTime" => true,
|
||||||
|
|
|
@ -44,7 +44,7 @@ switch ( $_REQUEST['command'] ) {
|
||||||
$remSockFile = ZM_PATH_SOCKS.'/zms-'.sprintf("%06d",$_REQUEST['connkey']).'s.sock';
|
$remSockFile = ZM_PATH_SOCKS.'/zms-'.sprintf("%06d",$_REQUEST['connkey']).'s.sock';
|
||||||
$max_socket_tries = 10;
|
$max_socket_tries = 10;
|
||||||
while ( !file_exists($remSockFile) && $max_socket_tries-- ) { //sometimes we are too fast for our own good, if it hasn't been setup yet give it a second.
|
while ( !file_exists($remSockFile) && $max_socket_tries-- ) { //sometimes we are too fast for our own good, if it hasn't been setup yet give it a second.
|
||||||
usleep(200000);
|
usleep(2000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !file_exists($remSockFile) ) {
|
if ( !file_exists($remSockFile) ) {
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
class Event {
|
class Event {
|
||||||
|
|
||||||
|
private $fields = array(
|
||||||
|
'Id',
|
||||||
|
'Name',
|
||||||
|
'MonitorId',
|
||||||
|
'StorageId',
|
||||||
|
'Name',
|
||||||
|
'DiskSpace',
|
||||||
|
);
|
||||||
public function __construct( $IdOrRow = null ) {
|
public function __construct( $IdOrRow = null ) {
|
||||||
$row = NULL;
|
$row = NULL;
|
||||||
if ( $IdOrRow ) {
|
if ( $IdOrRow ) {
|
||||||
|
@ -177,7 +186,10 @@ class Event {
|
||||||
return( $streamSrc );
|
return( $streamSrc );
|
||||||
} // end function getStreamSrc
|
} // end function getStreamSrc
|
||||||
|
|
||||||
function DiskSpace() {
|
function DiskSpace( $new='' ) {
|
||||||
|
if ( $new != '' ) {
|
||||||
|
$this->{'DiskSpace'} = $new;
|
||||||
|
}
|
||||||
if ( null === $this->{'DiskSpace'} ) {
|
if ( null === $this->{'DiskSpace'} ) {
|
||||||
$this->{'DiskSpace'} = folder_size( $this->Path() );
|
$this->{'DiskSpace'} = folder_size( $this->Path() );
|
||||||
dbQuery( 'UPDATE Events SET DiskSpace=? WHERE Id=?', array( $this->{'DiskSpace'}, $this->{'Id'} ) );
|
dbQuery( 'UPDATE Events SET DiskSpace=? WHERE Id=?', array( $this->{'DiskSpace'}, $this->{'Id'} ) );
|
||||||
|
@ -370,6 +382,13 @@ class Event {
|
||||||
return $filters;
|
return $filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function save( ) {
|
||||||
|
|
||||||
|
$sql = 'UPDATE Events SET '.implode(', ', array_map( function($field) {return $field.'=?';}, $this->fields ) ) . ' WHERE Id=?';
|
||||||
|
$values = array_map( function($field){return $this->{$field};}, $this->fields );
|
||||||
|
$values[] = $this->{'Id'};
|
||||||
|
dbQuery( $sql, $values );
|
||||||
|
}
|
||||||
|
|
||||||
} # end class
|
} # end class
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ public $defaults = array(
|
||||||
'AutoArchive' => 0,
|
'AutoArchive' => 0,
|
||||||
'AutoVideo' => 0,
|
'AutoVideo' => 0,
|
||||||
'AutoMessage' => 0,
|
'AutoMessage' => 0,
|
||||||
|
'UpdateDiskSpace' => 0,
|
||||||
'Background' => 0,
|
'Background' => 0,
|
||||||
'Concurrent' => 0,
|
'Concurrent' => 0,
|
||||||
'limit' => 100,
|
'limit' => 100,
|
||||||
|
|
|
@ -4,6 +4,17 @@ require_once( 'Server.php' );
|
||||||
|
|
||||||
class Monitor {
|
class Monitor {
|
||||||
|
|
||||||
|
private $defaults = array(
|
||||||
|
'Id' => null,
|
||||||
|
'Name' => '',
|
||||||
|
'StorageId' => 0,
|
||||||
|
'ServerId' => 0,
|
||||||
|
'Function' => 'None',
|
||||||
|
'Enabled' => 1,
|
||||||
|
'Width' => null,
|
||||||
|
'Height' => null,
|
||||||
|
'Orientation' => null,
|
||||||
|
);
|
||||||
private $control_fields = array(
|
private $control_fields = array(
|
||||||
'Name' => '',
|
'Name' => '',
|
||||||
'Type' => 'Local',
|
'Type' => 'Local',
|
||||||
|
@ -161,8 +172,9 @@ private $control_fields = array(
|
||||||
} else {
|
} else {
|
||||||
if ( array_key_exists($fn, $this->control_fields) ) {
|
if ( array_key_exists($fn, $this->control_fields) ) {
|
||||||
return $this->control_fields{$fn};
|
return $this->control_fields{$fn};
|
||||||
|
} else if ( array_key_exists( $fn, $this->defaults ) ) {
|
||||||
|
return $this->defaults{$fn};
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
$backTrace = debug_backtrace();
|
$backTrace = debug_backtrace();
|
||||||
$file = $backTrace[1]['file'];
|
$file = $backTrace[1]['file'];
|
||||||
$line = $backTrace[1]['line'];
|
$line = $backTrace[1]['line'];
|
||||||
|
@ -206,14 +218,19 @@ private $control_fields = array(
|
||||||
return( $streamSrc );
|
return( $streamSrc );
|
||||||
} // end function getStreamSrc
|
} // end function getStreamSrc
|
||||||
|
|
||||||
public function Width() {
|
public function Width( $new = null ) {
|
||||||
|
if ( $new )
|
||||||
|
$this->{'Width'} = $new;
|
||||||
|
|
||||||
if ( $this->Orientation() == '90' or $this->Orientation() == '270' ) {
|
if ( $this->Orientation() == '90' or $this->Orientation() == '270' ) {
|
||||||
return $this->{'Height'};
|
return $this->{'Height'};
|
||||||
}
|
}
|
||||||
return $this->{'Width'};
|
return $this->{'Width'};
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Height() {
|
public function Height( $new=null ) {
|
||||||
|
if ( $new )
|
||||||
|
$this->{'Height'} = $new;
|
||||||
if ( $this->Orientation() == '90' or $this->Orientation() == '270' ) {
|
if ( $this->Orientation() == '90' or $this->Orientation() == '270' ) {
|
||||||
return $this->{'Width'};
|
return $this->{'Width'};
|
||||||
}
|
}
|
||||||
|
@ -237,5 +254,121 @@ private $control_fields = array(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static function find_all( $parameters = null, $options = null ) {
|
||||||
|
$filters = array();
|
||||||
|
$sql = 'SELECT * FROM Monitors ';
|
||||||
|
$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, 'Monitor');
|
||||||
|
foreach ( $results as $row => $obj ) {
|
||||||
|
$filters[] = $obj;
|
||||||
|
}
|
||||||
|
return $filters;
|
||||||
|
}
|
||||||
|
public function save( $new_values = null ) {
|
||||||
|
|
||||||
|
|
||||||
|
if ( $new_values ) {
|
||||||
|
foreach ( $new_values as $k=>$v ) {
|
||||||
|
$this->{$k} = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$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 );
|
||||||
|
$values[] = $this->{'Id'};
|
||||||
|
dbQuery( $sql, $values );
|
||||||
|
} // end function save
|
||||||
|
function zmcControl( $mode=false ) {
|
||||||
|
if ( (!defined('ZM_SERVER_ID')) or ( ZM_SERVER_ID==$this->{'ServerId'} ) ) {
|
||||||
|
if ( $this->{'Type'} == 'Local' ) {
|
||||||
|
$zmcArgs = '-d '.$this->{'Device'};
|
||||||
|
} else {
|
||||||
|
$zmcArgs = '-m '.$this->{'Id'};
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $mode == 'stop' ) {
|
||||||
|
daemonControl( 'stop', 'zmc', $zmcArgs );
|
||||||
|
} else {
|
||||||
|
if ( $mode == 'restart' ) {
|
||||||
|
daemonControl( 'stop', 'zmc', $zmcArgs );
|
||||||
|
}
|
||||||
|
daemonControl( 'start', 'zmc', $zmcArgs );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$Server = $this->Server();
|
||||||
|
|
||||||
|
$url = $Server->Url() . '/zm/api/monitors/'.$this->{'Id'}.'.json';
|
||||||
|
if ( ZM_OPT_USE_AUTH ) {
|
||||||
|
if ( ZM_AUTH_RELAY == 'hashed' ) {
|
||||||
|
$url .= '&auth='.generateAuthHash( ZM_AUTH_HASH_IPS );
|
||||||
|
} elseif ( ZM_AUTH_RELAY == 'plain' ) {
|
||||||
|
$url = '&user='.$_SESSION['username'];
|
||||||
|
$url = '&pass='.$_SESSION['password'];
|
||||||
|
} elseif ( ZM_AUTH_RELAY == 'none' ) {
|
||||||
|
$url = '&user='.$_SESSION['username'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$data = array('Monitor[Function]' => $this->{'Function'} );
|
||||||
|
|
||||||
|
// use key 'http' even if you send the request to https://...
|
||||||
|
$options = array(
|
||||||
|
'http' => array(
|
||||||
|
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
|
||||||
|
'method' => 'POST',
|
||||||
|
'content' => http_build_query($data)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$context = stream_context_create($options);
|
||||||
|
$result = file_get_contents($url, false, $context);
|
||||||
|
if ($result === FALSE) { /* Handle error */ }
|
||||||
|
}
|
||||||
|
} // end function zmcControl
|
||||||
|
function zmaControl( $mode=false ) {
|
||||||
|
if ( (!defined('ZM_SERVER_ID')) or ( ZM_SERVER_ID==$this->{'ServerId'} ) ) {
|
||||||
|
if ( $this->{'Function'} == 'None' || $this->{'Function'} == 'Monitor' || $mode == 'stop' ) {
|
||||||
|
if ( ZM_OPT_CONTROL ) {
|
||||||
|
daemonControl( 'stop', 'zmtrack.pl', '-m '.$this->{'Id'} );
|
||||||
|
}
|
||||||
|
daemonControl( 'stop', 'zma', '-m '.$this->{'Id'} );
|
||||||
|
} else {
|
||||||
|
if ( $mode == 'restart' ) {
|
||||||
|
if ( ZM_OPT_CONTROL ) {
|
||||||
|
daemonControl( 'stop', 'zmtrack.pl', '-m '.$this->{'Id'} );
|
||||||
|
}
|
||||||
|
daemonControl( 'stop', 'zma', '-m '.$this->{'Id'} );
|
||||||
|
}
|
||||||
|
daemonControl( 'start', 'zma', '-m '.$this->{'Id'} );
|
||||||
|
if ( ZM_OPT_CONTROL && $this->{'Controllable'} && $this->{'TrackMotion'} && ( $this->{'Function'} == 'Modect' || $this->{'Function'} == 'Mocord' ) ) {
|
||||||
|
daemonControl( 'start', 'zmtrack.pl', '-m '.$this->{'Id'} );
|
||||||
|
}
|
||||||
|
if ( $mode == 'reload' ) {
|
||||||
|
daemonControl( 'reload', 'zma', '-m '.$this->{'Id'} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // end if we are on the recording server
|
||||||
|
}
|
||||||
|
} // end class Monitor
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once('database.php');
|
||||||
|
|
||||||
|
class MontageLayout {
|
||||||
|
|
||||||
|
private $defaults = array(
|
||||||
|
'Id' => null,
|
||||||
|
'Name' => '',
|
||||||
|
'Positions' => 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
public function __construct( $IdOrRow = NULL ) {
|
||||||
|
if ( $IdOrRow ) {
|
||||||
|
$row = NULL;
|
||||||
|
if ( is_integer( $IdOrRow ) or is_numeric( $IdOrRow ) ) {
|
||||||
|
$row = dbFetchOne( 'SELECT * FROM MontageLayouts WHERE Id=?', NULL, array( $IdOrRow ) );
|
||||||
|
if ( ! $row ) {
|
||||||
|
Error("Unable to load MontageLayout record for Id=" . $IdOrRow );
|
||||||
|
}
|
||||||
|
} elseif ( is_array( $IdOrRow ) ) {
|
||||||
|
$row = $IdOrRow;
|
||||||
|
} else {
|
||||||
|
Error("Unknown argument passed to MontageLayout Constructor ($IdOrRow)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $row ) {
|
||||||
|
foreach ($row as $k => $v) {
|
||||||
|
$this->{$k} = $v;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Error('No row for MontageLayout ' . $IdOrRow );
|
||||||
|
}
|
||||||
|
} # end if isset($IdOrRow)
|
||||||
|
} // end function __construct
|
||||||
|
|
||||||
|
public function __call($fn, array $args){
|
||||||
|
if ( count($args) ) {
|
||||||
|
$this->{$fn} = $args[0];
|
||||||
|
}
|
||||||
|
if ( array_key_exists($fn, $this) ) {
|
||||||
|
return $this->{$fn};
|
||||||
|
} else {
|
||||||
|
if ( array_key_exists( $fn, $this->defaults ) ) {
|
||||||
|
return $this->defaults{$fn};
|
||||||
|
} else {
|
||||||
|
$backTrace = debug_backtrace();
|
||||||
|
$file = $backTrace[1]['file'];
|
||||||
|
$line = $backTrace[1]['line'];
|
||||||
|
Warning( "Unknown function call MontageLayout->$fn from $file:$line" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set( $data ) {
|
||||||
|
foreach ($data as $k => $v) {
|
||||||
|
if ( is_array( $v ) ) {
|
||||||
|
# perhaps should turn into a comma-separated string
|
||||||
|
$this->{$k} = implode(',',$v);
|
||||||
|
} else if ( is_string( $v ) ) {
|
||||||
|
$this->{$k} = trim( $v );
|
||||||
|
} else if ( is_integer( $v ) ) {
|
||||||
|
$this->{$k} = $v;
|
||||||
|
} else if ( is_bool( $v ) ) {
|
||||||
|
$this->{$k} = $v;
|
||||||
|
} else {
|
||||||
|
Error( "Unknown type $k => $v of var " . gettype( $v ) );
|
||||||
|
$this->{$k} = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static function find( $parameters = null, $options = null ) {
|
||||||
|
$filters = array();
|
||||||
|
$sql = 'SELECT * FROM MontageLayouts ';
|
||||||
|
$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);
|
||||||
|
if ( $result ) {
|
||||||
|
$results = $result->fetchALL(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'MontageLayout');
|
||||||
|
foreach ( $results as $row => $obj ) {
|
||||||
|
$filters[] = $obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $filters;
|
||||||
|
}
|
||||||
|
public function save( $new_values = null ) {
|
||||||
|
if ( $new_values ) {
|
||||||
|
foreach ( $new_values as $k=>$v ) {
|
||||||
|
$this->{$k} = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = 'UPDATE MontageLayouts SET '.implode(', ', array_map( function($field) {return $field.'=?';}, array_keys( $this->defaults ) ) ) . ' WHERE Id=?';
|
||||||
|
$values = array_map( function($field){return $this->{$field};}, $this->fields );
|
||||||
|
$values[] = $this->{'Id'};
|
||||||
|
dbQuery( $sql, $values );
|
||||||
|
} // end function save
|
||||||
|
|
||||||
|
} // end class MontageLayout
|
||||||
|
?>
|
|
@ -113,7 +113,9 @@ class Storage {
|
||||||
if ( ! array_key_exists( 'disk_used_space', $this ) ) {
|
if ( ! array_key_exists( 'disk_used_space', $this ) ) {
|
||||||
$used = 0;
|
$used = 0;
|
||||||
if ( $this->{'Type'} == 's3fs' ) {
|
if ( $this->{'Type'} == 's3fs' ) {
|
||||||
foreach ( Event::find_all( array( 'StorageId'=>$this->Id() ) ) as $Event ) {
|
$used = dbFetchOne('SELECT SUM(DiskSpace) AS DiskSpace FROM Events WHERE StorageId=? AND DiskSpace IS NOT NULL', 'DiskSpace', array($this->Id()) );
|
||||||
|
|
||||||
|
foreach ( Event::find_all( array( 'StorageId'=>$this->Id(), 'DiskSpace'=>null ) ) as $Event ) {
|
||||||
$Event->Storage( $this ); // Prevent further db hit
|
$Event->Storage( $this ); // Prevent further db hit
|
||||||
$used += $Event->DiskSpace();
|
$used += $Event->DiskSpace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,28 @@
|
||||||
// credit: http://wezfurlong.org/blog/2006/nov/http-post-from-php-without-curl/
|
// credit: http://wezfurlong.org/blog/2006/nov/http-post-from-php-without-curl/
|
||||||
|
|
||||||
|
|
||||||
|
function do_request($method, $url, $data=array(), $optional_headers = null) {
|
||||||
|
global $php_errormsg;
|
||||||
|
|
||||||
|
$params = array('http' => array(
|
||||||
|
'method' => $method,
|
||||||
|
'content' => $data
|
||||||
|
));
|
||||||
|
if ($optional_headers !== null) {
|
||||||
|
$params['http']['header'] = $optional_headers;
|
||||||
|
}
|
||||||
|
$ctx = stream_context_create($params);
|
||||||
|
$fp = @fopen($url, 'rb', false, $ctx);
|
||||||
|
if (!$fp) {
|
||||||
|
throw new Exception("Problem with $url, $php_errormsg");
|
||||||
|
}
|
||||||
|
$response = @stream_get_contents($fp);
|
||||||
|
if ($response === false) {
|
||||||
|
throw new Exception("Problem reading data from $url, $php_errormsg");
|
||||||
|
}
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
function do_post_request($url, $data, $optional_headers = null) {
|
function do_post_request($url, $data, $optional_headers = null) {
|
||||||
$params = array('http' => array(
|
$params = array('http' => array(
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
|
@ -148,6 +170,7 @@ Warning("Addterm");
|
||||||
$sql .= ', AutoExecute = '. ( !empty($_REQUEST['filter']['AutoExecute']) ? 1 : 0);
|
$sql .= ', AutoExecute = '. ( !empty($_REQUEST['filter']['AutoExecute']) ? 1 : 0);
|
||||||
$sql .= ', AutoExecuteCmd = '.dbEscape($_REQUEST['filter']['AutoExecuteCmd']);
|
$sql .= ', AutoExecuteCmd = '.dbEscape($_REQUEST['filter']['AutoExecuteCmd']);
|
||||||
$sql .= ', AutoDelete = '. ( !empty($_REQUEST['filter']['AutoDelete']) ? 1 : 0);
|
$sql .= ', AutoDelete = '. ( !empty($_REQUEST['filter']['AutoDelete']) ? 1 : 0);
|
||||||
|
$sql .= ', UpdateDiskSpace = '. ( !empty($_REQUEST['filter']['UpdateDiskSpace']) ? 1 : 0);
|
||||||
$sql .= ', Background = '. ( !empty($_REQUEST['filter']['Background']) ? 1 : 0);
|
$sql .= ', Background = '. ( !empty($_REQUEST['filter']['Background']) ? 1 : 0);
|
||||||
$sql .= ', Concurrent = '. ( !empty($_REQUEST['filter']['Concurrent']) ? 1 : 0);
|
$sql .= ', Concurrent = '. ( !empty($_REQUEST['filter']['Concurrent']) ? 1 : 0);
|
||||||
|
|
||||||
|
@ -266,6 +289,30 @@ Warning("Addterm");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( isset($_REQUEST['object']) and $_REQUEST['object'] == 'Monitor' ) {
|
||||||
|
if ( $action == 'save' ) {
|
||||||
|
foreach ( $_REQUEST['mids'] as $mid ) {
|
||||||
|
$mid = ValidInt( $mid );
|
||||||
|
if ( ! canEdit('Monitors', $mid ) ) {
|
||||||
|
Warning("Cannot edit monitor $mid");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$Monitor = new Monitor( $mid );
|
||||||
|
$Monitor->zmaControl('stop');
|
||||||
|
$Monitor->zmcControl('stop');
|
||||||
|
$Monitor->save( $_REQUEST['newMonitor'] );
|
||||||
|
if ($Monitor->Function() != 'None' ) {
|
||||||
|
$Monitor->zmcControl('start');
|
||||||
|
if ( $Monitor->Enabled() ) {
|
||||||
|
$Monitor->zmaControl('start');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end foreach mid
|
||||||
|
$refreshParent = true;
|
||||||
|
} // end if action == save
|
||||||
|
} // end if object is Monitor
|
||||||
|
|
||||||
// Monitor edit actions, require a monitor id and edit permissions for that monitor
|
// Monitor edit actions, require a monitor id and edit permissions for that monitor
|
||||||
if ( !empty($_REQUEST['mid']) && canEdit( 'Monitors', $_REQUEST['mid'] ) ) {
|
if ( !empty($_REQUEST['mid']) && canEdit( 'Monitors', $_REQUEST['mid'] ) ) {
|
||||||
$mid = validInt($_REQUEST['mid']);
|
$mid = validInt($_REQUEST['mid']);
|
||||||
|
|
|
@ -127,10 +127,10 @@ function dbQuery( $sql, $params=NULL ) {
|
||||||
} else {
|
} else {
|
||||||
$result = $dbConn->query( $sql );
|
$result = $dbConn->query( $sql );
|
||||||
}
|
}
|
||||||
//if ( $params )
|
if ( $params )
|
||||||
//Warning("SQL: $sql" . implode(',',$params));
|
Warning("SQL: $sql" . implode(',',$params));
|
||||||
//else
|
else
|
||||||
//Warning("SQL: $sql" );
|
Warning("SQL: $sql" );
|
||||||
} catch(PDOException $e) {
|
} catch(PDOException $e) {
|
||||||
Error( "SQL-ERR '".$e->getMessage()."', statement was '".$sql."' params:" . implode(',',$params) );
|
Error( "SQL-ERR '".$e->getMessage()."', statement was '".$sql."' params:" . implode(',',$params) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -853,81 +853,17 @@ function daemonControl( $command, $daemon=false, $args=false ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function zmcControl( $monitor, $mode=false ) {
|
function zmcControl( $monitor, $mode=false ) {
|
||||||
if ( (!defined('ZM_SERVER_ID')) or ( ZM_SERVER_ID==$monitor['ServerId'] ) ) {
|
$Monitor = new Monitor( $monitor );
|
||||||
$row = NULL;
|
return $Monitor->zmcControl($mode);
|
||||||
if ( $monitor['Type'] == 'Local' ) {
|
|
||||||
$row = dbFetchOne( "SELECT count(if(Function!='None',1,NULL)) AS ActiveCount FROM Monitors WHERE Device = ?", NULL, array($monitor['Device']) );
|
|
||||||
$zmcArgs = '-d '.$monitor['Device'];
|
|
||||||
} else {
|
|
||||||
$row = dbFetchOne( "SELECT count(if(Function!='None',1,NULL)) AS ActiveCount FROM Monitors WHERE Id = ?", NULL, array($monitor['Id']) );
|
|
||||||
$zmcArgs = '-m '.$monitor['Id'];
|
|
||||||
}
|
|
||||||
$activeCount = $row['ActiveCount'];
|
|
||||||
|
|
||||||
if ( (!$activeCount) || ($mode == 'stop') ) {
|
|
||||||
daemonControl( 'stop', 'zmc', $zmcArgs );
|
|
||||||
} else {
|
|
||||||
if ( $mode == 'restart' ) {
|
|
||||||
daemonControl( 'stop', 'zmc', $zmcArgs );
|
|
||||||
}
|
|
||||||
daemonControl( 'start', 'zmc', $zmcArgs );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$Server = new Server( $monitor['ServerId'] );
|
|
||||||
|
|
||||||
$url = $Server->Url() . '/zm/api/monitors/'.$monitor['Id'].'.json';
|
|
||||||
if ( ZM_OPT_USE_AUTH ) {
|
|
||||||
if ( ZM_AUTH_RELAY == 'hashed' ) {
|
|
||||||
$url .= '&auth='.generateAuthHash( ZM_AUTH_HASH_IPS );
|
|
||||||
} elseif ( ZM_AUTH_RELAY == 'plain' ) {
|
|
||||||
$url = '&user='.$_SESSION['username'];
|
|
||||||
$url = '&pass='.$_SESSION['password'];
|
|
||||||
} elseif ( ZM_AUTH_RELAY == 'none' ) {
|
|
||||||
$url = '&user='.$_SESSION['username'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$data = array('Monitor[Function]' => $monitor['Function'] );
|
|
||||||
|
|
||||||
// use key 'http' even if you send the request to https://...
|
|
||||||
$options = array(
|
|
||||||
'http' => array(
|
|
||||||
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
|
|
||||||
'method' => 'POST',
|
|
||||||
'content' => http_build_query($data)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$context = stream_context_create($options);
|
|
||||||
$result = file_get_contents($url, false, $context);
|
|
||||||
if ($result === FALSE) { /* Handle error */ }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function zmaControl( $monitor, $mode=false ) {
|
function zmaControl( $monitor, $mode=false ) {
|
||||||
if ( !is_array( $monitor ) ) {
|
if ( !is_array( $monitor ) ) {
|
||||||
|
$monitor =
|
||||||
$monitor = dbFetchOne( 'select C.*, M.* from Monitors as M left join Controls as C on (M.ControlId = C.Id ) where M.Id=?', NULL, array($monitor) );
|
$monitor = dbFetchOne( 'select C.*, M.* from Monitors as M left join Controls as C on (M.ControlId = C.Id ) where M.Id=?', NULL, array($monitor) );
|
||||||
}
|
}
|
||||||
if ( (!defined('ZM_SERVER_ID')) or ( ZM_SERVER_ID==$monitor['ServerId'] ) ) {
|
$Monitor = new Monitor( $monitor );
|
||||||
if ( !$monitor || $monitor['Function'] == 'None' || $monitor['Function'] == 'Monitor' || $mode == 'stop' ) {
|
$Monitor->zmaControl($mode);
|
||||||
if ( ZM_OPT_CONTROL ) {
|
|
||||||
daemonControl( 'stop', 'zmtrack.pl', '-m '.$monitor['Id'] );
|
|
||||||
}
|
|
||||||
daemonControl( 'stop', 'zma', '-m '.$monitor['Id'] );
|
|
||||||
} else {
|
|
||||||
if ( $mode == 'restart' ) {
|
|
||||||
if ( ZM_OPT_CONTROL ) {
|
|
||||||
daemonControl( 'stop', 'zmtrack.pl', '-m '.$monitor['Id'] );
|
|
||||||
}
|
|
||||||
daemonControl( 'stop', 'zma', '-m '.$monitor['Id'] );
|
|
||||||
}
|
|
||||||
daemonControl( 'start', 'zma', '-m '.$monitor['Id'] );
|
|
||||||
if ( ZM_OPT_CONTROL && $monitor['Controllable'] && $monitor['TrackMotion'] && ( $monitor['Function'] == 'Modect' || $monitor['Function'] == 'Mocord' ) ) {
|
|
||||||
daemonControl( 'start', 'zmtrack.pl', '-m '.$monitor['Id'] );
|
|
||||||
}
|
|
||||||
if ( $mode == 'reload' ) {
|
|
||||||
daemonControl( 'reload', 'zma', '-m '.$monitor['Id'] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // end if we are on the recording server
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function initDaemonStatus() {
|
function initDaemonStatus() {
|
||||||
|
@ -1121,10 +1057,17 @@ function parseSort( $saveToSession=false, $querySep='&' ) {
|
||||||
$sortColumn = 'E.Cause';
|
$sortColumn = 'E.Cause';
|
||||||
break;
|
break;
|
||||||
case 'DateTime' :
|
case 'DateTime' :
|
||||||
$_REQUEST['sort_field'] = 'StartTime';
|
$sortColumn = 'E.StartTime';
|
||||||
|
break;
|
||||||
|
case 'DiskSpace' :
|
||||||
|
$sortColumn = 'E.DiskSpace';
|
||||||
|
break;
|
||||||
case 'StartTime' :
|
case 'StartTime' :
|
||||||
$sortColumn = 'E.StartTime';
|
$sortColumn = 'E.StartTime';
|
||||||
break;
|
break;
|
||||||
|
case 'EndTime' :
|
||||||
|
$sortColumn = 'E.EndTime';
|
||||||
|
break;
|
||||||
case 'Length' :
|
case 'Length' :
|
||||||
$sortColumn = 'E.Length';
|
$sortColumn = 'E.Length';
|
||||||
break;
|
break;
|
||||||
|
@ -1190,6 +1133,7 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) {
|
||||||
case 'ServerId':
|
case 'ServerId':
|
||||||
$filter['sql'] .= 'M.ServerId';
|
$filter['sql'] .= 'M.ServerId';
|
||||||
break;
|
break;
|
||||||
|
# Unspecified start or end, so assume start, this is to support legacy filters
|
||||||
case 'DateTime':
|
case 'DateTime':
|
||||||
$filter['sql'] .= 'E.StartTime';
|
$filter['sql'] .= 'E.StartTime';
|
||||||
break;
|
break;
|
||||||
|
@ -1202,8 +1146,35 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) {
|
||||||
case 'Weekday':
|
case 'Weekday':
|
||||||
$filter['sql'] .= 'weekday( E.StartTime )';
|
$filter['sql'] .= 'weekday( E.StartTime )';
|
||||||
break;
|
break;
|
||||||
|
# Starting Time
|
||||||
|
case 'StartDateTime':
|
||||||
|
$filter['sql'] .= 'E.StartTime';
|
||||||
|
break;
|
||||||
|
case 'StartDate':
|
||||||
|
$filter['sql'] .= 'to_days( E.StartTime )';
|
||||||
|
break;
|
||||||
|
case 'StartTime':
|
||||||
|
$filter['sql'] .= 'extract( hour_second from E.StartTime )';
|
||||||
|
break;
|
||||||
|
case 'StartWeekday':
|
||||||
|
$filter['sql'] .= 'weekday( E.StartTime )';
|
||||||
|
break;
|
||||||
|
# Ending Time
|
||||||
|
case 'EndDateTime':
|
||||||
|
$filter['sql'] .= 'E.EndTime';
|
||||||
|
break;
|
||||||
|
case 'EndDate':
|
||||||
|
$filter['sql'] .= 'to_days( E.EndTime )';
|
||||||
|
break;
|
||||||
|
case 'EndTime':
|
||||||
|
$filter['sql'] .= 'extract( hour_second from E.EndTime )';
|
||||||
|
break;
|
||||||
|
case 'EndWeekday':
|
||||||
|
$filter['sql'] .= 'weekday( E.EndTime )';
|
||||||
|
break;
|
||||||
case 'Id':
|
case 'Id':
|
||||||
case 'Name':
|
case 'Name':
|
||||||
|
case 'DiskSpace':
|
||||||
case 'MonitorId':
|
case 'MonitorId':
|
||||||
case 'StorageId':
|
case 'StorageId':
|
||||||
case 'Length':
|
case 'Length':
|
||||||
|
@ -1303,6 +1274,10 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) {
|
||||||
case '![]' :
|
case '![]' :
|
||||||
$filter['sql'] .= ' not in ('.join( ',', $valueList ).')';
|
$filter['sql'] .= ' not in ('.join( ',', $valueList ).')';
|
||||||
break;
|
break;
|
||||||
|
case 'IS' :
|
||||||
|
$filter['sql'] .= " IS $value";
|
||||||
|
case 'IS NOT' :
|
||||||
|
$filter['sql'] .= " IS NOT $value";
|
||||||
}
|
}
|
||||||
|
|
||||||
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][op]").'='.urlencode($terms[$i]['op']);
|
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][op]").'='.urlencode($terms[$i]['op']);
|
||||||
|
@ -1917,7 +1892,8 @@ function logState() {
|
||||||
Logger::WARNING => array( ZM_LOG_ALERT_WAR_COUNT, ZM_LOG_ALARM_WAR_COUNT ),
|
Logger::WARNING => array( ZM_LOG_ALERT_WAR_COUNT, ZM_LOG_ALARM_WAR_COUNT ),
|
||||||
);
|
);
|
||||||
|
|
||||||
$sql = "select Level, count(Level) as LevelCount from Logs where Level < ".Logger::INFO." and TimeKey > unix_timestamp(now() - interval ".ZM_LOG_CHECK_PERIOD." second) group by Level order by Level asc";
|
# This is an expensive request, as it has to hit every row of the Logs Table
|
||||||
|
$sql = 'SELECT Level, COUNT(Level) AS LevelCount FROM Logs WHERE Level < '.Logger::INFO.' AND TimeKey > unix_timestamp(now() - interval '.ZM_LOG_CHECK_PERIOD.' second) GROUP BY Level ORDER BY Level ASC';
|
||||||
$counts = dbFetchAll( $sql );
|
$counts = dbFetchAll( $sql );
|
||||||
|
|
||||||
foreach ( $counts as $count ) {
|
foreach ( $counts as $count ) {
|
||||||
|
|
|
@ -34,7 +34,7 @@ if ( version_compare( phpversion(), '4.1.0', '<') ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Useful debugging lines for mobile devices
|
// Useful debugging lines for mobile devices
|
||||||
if ( false ) {
|
if ( true ) {
|
||||||
ob_start();
|
ob_start();
|
||||||
phpinfo( INFO_VARIABLES );
|
phpinfo( INFO_VARIABLES );
|
||||||
$fp = fopen( '/tmp/env.html', 'w' );
|
$fp = fopen( '/tmp/env.html', 'w' );
|
||||||
|
|
|
@ -116,8 +116,11 @@ $SLANG = array(
|
||||||
'AttrArchiveStatus' => 'Archive Status',
|
'AttrArchiveStatus' => 'Archive Status',
|
||||||
'AttrAvgScore' => 'Avg. Score',
|
'AttrAvgScore' => 'Avg. Score',
|
||||||
'AttrCause' => 'Cause',
|
'AttrCause' => 'Cause',
|
||||||
'AttrDate' => 'Date',
|
'AttrStartDate' => 'Start Date',
|
||||||
'AttrDateTime' => 'Date/Time',
|
'AttrEndDate' => 'End Date',
|
||||||
|
'AttrStartDateTime' => 'Start Date/Time',
|
||||||
|
'AttrEndDateTime' => 'End Date/Time',
|
||||||
|
'AttrDiskSpace' => 'Disk Space',
|
||||||
'AttrDiskBlocks' => 'Disk Blocks',
|
'AttrDiskBlocks' => 'Disk Blocks',
|
||||||
'AttrDiskPercent' => 'Disk Percent',
|
'AttrDiskPercent' => 'Disk Percent',
|
||||||
'AttrDuration' => 'Duration',
|
'AttrDuration' => 'Duration',
|
||||||
|
@ -132,9 +135,11 @@ $SLANG = array(
|
||||||
'AttrName' => 'Name',
|
'AttrName' => 'Name',
|
||||||
'AttrNotes' => 'Notes',
|
'AttrNotes' => 'Notes',
|
||||||
'AttrSystemLoad' => 'System Load',
|
'AttrSystemLoad' => 'System Load',
|
||||||
'AttrTime' => 'Time',
|
'AttrStartTime' => 'Start Time',
|
||||||
|
'AttrEndTime' => 'End Time',
|
||||||
'AttrTotalScore' => 'Total Score',
|
'AttrTotalScore' => 'Total Score',
|
||||||
'AttrWeekday' => 'Weekday',
|
'AttrStartWeekday' => 'Start Weekday',
|
||||||
|
'AttrEndWeekday' => 'End Weekday',
|
||||||
'Auto' => 'Auto',
|
'Auto' => 'Auto',
|
||||||
'AutoStopTimeout' => 'Auto Stop Timeout',
|
'AutoStopTimeout' => 'Auto Stop Timeout',
|
||||||
'Available' => 'Available',
|
'Available' => 'Available',
|
||||||
|
@ -334,6 +339,7 @@ $SLANG = array(
|
||||||
'Ffmpeg' => 'Ffmpeg',
|
'Ffmpeg' => 'Ffmpeg',
|
||||||
'File' => 'File',
|
'File' => 'File',
|
||||||
'FilterArchiveEvents' => 'Archive all matches',
|
'FilterArchiveEvents' => 'Archive all matches',
|
||||||
|
'FilterUpdateDiskSpace' => 'Update used disk space',
|
||||||
'FilterDeleteEvents' => 'Delete all matches',
|
'FilterDeleteEvents' => 'Delete all matches',
|
||||||
'FilterEmailEvents' => 'Email details of all matches',
|
'FilterEmailEvents' => 'Email details of all matches',
|
||||||
'FilterExecuteEvents' => 'Execute command on all matches',
|
'FilterExecuteEvents' => 'Execute command on all matches',
|
||||||
|
@ -413,6 +419,7 @@ $SLANG = array(
|
||||||
'LimitResultsPre' => 'Limit to first', // This is used at the beginning of the phrase 'Limit to first N results only'
|
'LimitResultsPre' => 'Limit to first', // This is used at the beginning of the phrase 'Limit to first N results only'
|
||||||
'LinkedMonitors' => 'Linked Monitors',
|
'LinkedMonitors' => 'Linked Monitors',
|
||||||
'List' => 'List',
|
'List' => 'List',
|
||||||
|
'ListMatches' => 'List Matches',
|
||||||
'Load' => 'Load',
|
'Load' => 'Load',
|
||||||
'Local' => 'Local',
|
'Local' => 'Local',
|
||||||
'Log' => 'Log',
|
'Log' => 'Log',
|
||||||
|
@ -549,6 +556,8 @@ $SLANG = array(
|
||||||
'OpNe' => 'not equal to',
|
'OpNe' => 'not equal to',
|
||||||
'OpNotIn' => 'not in set',
|
'OpNotIn' => 'not in set',
|
||||||
'OpNotMatches' => 'does not match',
|
'OpNotMatches' => 'does not match',
|
||||||
|
'OpIs' => 'is',
|
||||||
|
'OpIsNot' => 'is not',
|
||||||
'OptionalEncoderParam' => 'Optional Encoder Parameters',
|
'OptionalEncoderParam' => 'Optional Encoder Parameters',
|
||||||
'OptionHelp' => 'Option Help',
|
'OptionHelp' => 'Option Help',
|
||||||
'OptionRestartWarning' => 'These changes may not come into effect fully\nwhile the system is running. When you have\nfinished making your changes please ensure that\nyou restart ZoneMinder.',
|
'OptionRestartWarning' => 'These changes may not come into effect fully\nwhile the system is running. When you have\nfinished making your changes please ensure that\nyou restart ZoneMinder.',
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
.vjsMessage {
|
#content .vjsMessage {
|
||||||
font-size: 2em;
|
width: 100%;
|
||||||
line-height: 1.5;
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
z-index: 10;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 200%;
|
||||||
color: white;
|
color: white;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -40,6 +44,7 @@ span.noneCue {
|
||||||
|
|
||||||
#eventVideo {
|
#eventVideo {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
postion: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
#menuBar1 {
|
#menuBar1 {
|
||||||
|
@ -112,6 +117,8 @@ span.noneCue {
|
||||||
}
|
}
|
||||||
|
|
||||||
#imageFeed {
|
#imageFeed {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
.vjsMessage {
|
#content .vjsMessage {
|
||||||
font-size: 2em;
|
width: 100%;
|
||||||
line-height: 1.5;
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
z-index: 10;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 200%;
|
||||||
color: white;
|
color: white;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -95,6 +99,8 @@ span.noneCue {
|
||||||
}
|
}
|
||||||
|
|
||||||
#imageFeed {
|
#imageFeed {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,6 +262,7 @@ span.noneCue {
|
||||||
|
|
||||||
#eventVideo {
|
#eventVideo {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
#thumbsKnob {
|
#thumbsKnob {
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
.vjsMessage {
|
#content .vjsMessage {
|
||||||
font-size: 2em;
|
width: 100%;
|
||||||
line-height: 1.5;
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
z-index: 10;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 200%;
|
||||||
color: white;
|
color: white;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -100,6 +104,8 @@ span.noneCue {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
#imageFeed {
|
#imageFeed {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,6 +278,7 @@ span.noneCue {
|
||||||
}
|
}
|
||||||
#eventVideo {
|
#eventVideo {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
#video-controls {
|
#video-controls {
|
||||||
|
|
|
@ -31,6 +31,7 @@ $rates = array(
|
||||||
);
|
);
|
||||||
|
|
||||||
$scales = array(
|
$scales = array(
|
||||||
|
'auto' => translate('Scale to Fit'),
|
||||||
'' => translate('Fixed Width/Height'),
|
'' => translate('Fixed Width/Height'),
|
||||||
'400' => '4x',
|
'400' => '4x',
|
||||||
'300' => '3x',
|
'300' => '3x',
|
||||||
|
@ -44,6 +45,8 @@ $scales = array(
|
||||||
'12.5' => '1/8x',
|
'12.5' => '1/8x',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (isset($_REQUEST['view'])) unset($scales[$_REQUEST['view'] == 'event' ? '' : 'auto']); //Remove the option we aren't using on montage or event
|
||||||
|
|
||||||
$bandwidth_options = array(
|
$bandwidth_options = array(
|
||||||
'high' => translate('High'),
|
'high' => translate('High'),
|
||||||
'medium' => translate('Medium'),
|
'medium' => translate('Medium'),
|
||||||
|
|
|
@ -194,9 +194,19 @@ ZoneMinder requires Javascript. Please enable Javascript in your browser for thi
|
||||||
<li><a href="?view=console"><?php echo translate('Console') ?></a></li>
|
<li><a href="?view=console"><?php echo translate('Console') ?></a></li>
|
||||||
<?php if ( canView( 'System' ) ) { ?>
|
<?php if ( canView( 'System' ) ) { ?>
|
||||||
<li><a href="?view=options"><?php echo translate('Options') ?></a></li>
|
<li><a href="?view=options"><?php echo translate('Options') ?></a></li>
|
||||||
<li><?php if ( logToDatabase() > Logger::NOLOG ) { ?> <?php echo makePopupLink( '?view=log', 'zmLog', 'log', '<span class="'.logState().'">'.translate('Log').'</span>' ) ?><?php } ?></li>
|
<li>
|
||||||
<?php } ?>
|
<?php
|
||||||
<?php if ( ZM_OPT_X10 && canView( 'Devices' ) ) { ?>
|
if ( logToDatabase() > Logger::NOLOG ) {
|
||||||
|
if ( ! ZM_RUN_AUDIT ) {
|
||||||
|
# zmaudit can clean the logs, but if we aren't running it, then we should clecan them regularly
|
||||||
|
dbQuery("DELETE FROM Logs WHERE TimeKey < NOW()-to_days('".ZM_LOG_DATABASE_LIMIT."')");
|
||||||
|
}
|
||||||
|
echo makePopupLink( '?view=log', 'zmLog', 'log', '<span class="'.logState().'">'.translate('Log').'</span>' );
|
||||||
|
}
|
||||||
|
} // end if canview(System)
|
||||||
|
?></li>
|
||||||
|
<?php
|
||||||
|
if ( ZM_OPT_X10 && canView( 'Devices' ) ) { ?>
|
||||||
<li><a href="?view=devices">Devices</a></li>
|
<li><a href="?view=devices">Devices</a></li>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
<li><a href="?view=groups"<?php echo $view=='groups'?' class="selected"':''?>><?php echo translate('Groups') ?></a></li>
|
<li><a href="?view=groups"<?php echo $view=='groups'?' class="selected"':''?>><?php echo translate('Groups') ?></a></li>
|
||||||
|
|
|
@ -41,7 +41,7 @@ var popupSizes = {
|
||||||
'frame': { 'addWidth': 32, 'minWidth': 384, 'addHeight': 200 },
|
'frame': { 'addWidth': 32, 'minWidth': 384, 'addHeight': 200 },
|
||||||
'frames': { 'width': 600, 'height': 700 },
|
'frames': { 'width': 600, 'height': 700 },
|
||||||
'function': { 'width': 400, 'height': 250 },
|
'function': { 'width': 400, 'height': 250 },
|
||||||
'group': { 'width': 360, 'height': 320 },
|
'group': { 'width': 660, 'height': 520 },
|
||||||
'groups': { 'width': 440, 'height': 220 },
|
'groups': { 'width': 440, 'height': 220 },
|
||||||
'image': { 'addWidth': 48, 'addHeight': 80 },
|
'image': { 'addWidth': 48, 'addHeight': 80 },
|
||||||
'log': { 'width': 1080, 'height': 720 },
|
'log': { 'width': 1080, 'height': 720 },
|
||||||
|
@ -51,6 +51,7 @@ var popupSizes = {
|
||||||
'monitorpreset':{ 'width': 440, 'height': 200 },
|
'monitorpreset':{ 'width': 440, 'height': 200 },
|
||||||
'monitorprobe': { 'width': 500, 'height': 240 },
|
'monitorprobe': { 'width': 500, 'height': 240 },
|
||||||
'monitorselect':{ 'width': 160, 'height': 200 },
|
'monitorselect':{ 'width': 160, 'height': 200 },
|
||||||
|
'monitors': { 'width': 300, 'height': 640 },
|
||||||
'montage': { 'width': -1, 'height': -1 },
|
'montage': { 'width': -1, 'height': -1 },
|
||||||
'onvifprobe': { 'width': 700, 'height': 550 },
|
'onvifprobe': { 'width': 700, 'height': 550 },
|
||||||
'optionhelp': { 'width': 400, 'height': 320 },
|
'optionhelp': { 'width': 400, 'height': 320 },
|
||||||
|
|
|
@ -283,6 +283,17 @@ function convertLabelFormat(LabelFormat, monitorName){
|
||||||
}
|
}
|
||||||
|
|
||||||
function addVideoTimingTrack(video, LabelFormat, monitorName, duration, startTime){
|
function addVideoTimingTrack(video, LabelFormat, monitorName, duration, startTime){
|
||||||
|
//This is a hacky way to handle changing the texttrack. If we ever upgrade vjs in a revamp replace this. Old method preserved because it's the right way.
|
||||||
|
let cues = vid.textTracks()[0].cues();
|
||||||
|
let labelFormat = convertLabelFormat(LabelFormat, monitorName);
|
||||||
|
startTime = moment(startTime);
|
||||||
|
|
||||||
|
for (let i = 0; i <= duration; i++) {
|
||||||
|
cues[i] = {id: i, index: i, startTime: i, Ca: i+1, text: startTime.format(labelFormat)};
|
||||||
|
startTime.add(1, 's');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
var labelFormat = convertLabelFormat(LabelFormat, monitorName);
|
var labelFormat = convertLabelFormat(LabelFormat, monitorName);
|
||||||
var webvttformat = 'HH:mm:ss.SSS', webvttdata="WEBVTT\n\n";
|
var webvttformat = 'HH:mm:ss.SSS', webvttdata="WEBVTT\n\n";
|
||||||
|
|
||||||
|
@ -304,6 +315,7 @@ function addVideoTimingTrack(video, LabelFormat, monitorName, duration, startTim
|
||||||
track.src = 'data:plain/text;charset=utf-8,'+encodeURIComponent(webvttdata);
|
track.src = 'data:plain/text;charset=utf-8,'+encodeURIComponent(webvttdata);
|
||||||
video.appendChild(track);
|
video.appendChild(track);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
function changeGroup( e, depth ) {
|
function changeGroup( e, depth ) {
|
||||||
var group_id = $('group'+depth).get('value');
|
var group_id = $('group'+depth).get('value');
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
font-size: .3em;
|
font-size: .3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vjs-default-skin.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar.vjs-zm {
|
.vjs-default-skin.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
bottom: -2em;
|
bottom: -2em;
|
||||||
|
|
|
@ -177,13 +177,31 @@ $groupSql = Group::get_group_sql( $group_id );
|
||||||
$displayMonitors = array();
|
$displayMonitors = array();
|
||||||
$monitors_dropdown = array(''=>'All');
|
$monitors_dropdown = array(''=>'All');
|
||||||
|
|
||||||
|
if ( $monitor_id ) {
|
||||||
|
$found_selected_monitor = false;
|
||||||
|
|
||||||
for ( $i = 0; $i < count($monitors); $i++ ) {
|
for ( $i = 0; $i < count($monitors); $i++ ) {
|
||||||
if ( $monitor_id and ( $monitors[$i]['Id'] != $monitor_id ) ) {
|
if ( !visibleMonitor( $monitors[$i]['Id'] ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
$monitors_dropdown[$monitors[$i]['Id']] = $monitors[$i]['Name'];
|
||||||
|
if ( $monitors[$i]['Id'] == $monitor_id ) {
|
||||||
|
$found_selected_monitor = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( ! $found_selected_monitor ) {
|
||||||
|
$monitor_id = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( $i = 0; $i < count($monitors); $i++ ) {
|
||||||
if ( !visibleMonitor( $monitors[$i]['Id'] ) ) {
|
if ( !visibleMonitor( $monitors[$i]['Id'] ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
$monitors_dropdown[$monitors[$i]['Id']] = $monitors[$i]['Name'];
|
||||||
|
|
||||||
|
if ( $monitor_id and ( $monitors[$i]['Id'] != $monitor_id ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if ( $monitors[$i]['Function'] != 'None' ) {
|
if ( $monitors[$i]['Function'] != 'None' ) {
|
||||||
$scaleWidth = reScale( $monitors[$i]['Width'], $monitors[$i]['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
|
$scaleWidth = reScale( $monitors[$i]['Width'], $monitors[$i]['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
|
||||||
$scaleHeight = reScale( $monitors[$i]['Height'], $monitors[$i]['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
|
$scaleHeight = reScale( $monitors[$i]['Height'], $monitors[$i]['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
|
||||||
|
@ -191,7 +209,6 @@ $groupSql = Group::get_group_sql( $group_id );
|
||||||
if ( $maxHeight < $scaleHeight ) $maxHeight = $scaleHeight;
|
if ( $maxHeight < $scaleHeight ) $maxHeight = $scaleHeight;
|
||||||
}
|
}
|
||||||
$displayMonitors[] = $monitors[$i];
|
$displayMonitors[] = $monitors[$i];
|
||||||
$monitors_dropdown[$monitors[$i]['Id']] = $monitors[$i]['Name'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -210,10 +227,10 @@ for( $i = 0; $i < count($displayMonitors); $i += 1 ) {
|
||||||
for ( $j = 0; $j < count($eventCounts); $j += 1 ) {
|
for ( $j = 0; $j < count($eventCounts); $j += 1 ) {
|
||||||
$filter = addFilterTerm( $eventCounts[$j]['filter'], count($eventCounts[$j]['filter']['Query']['terms']), array( 'cnj' => 'and', 'attr' => 'MonitorId', 'op' => '=', 'val' => $monitor['Id'] ) );
|
$filter = addFilterTerm( $eventCounts[$j]['filter'], count($eventCounts[$j]['filter']['Query']['terms']), array( 'cnj' => 'and', 'attr' => 'MonitorId', 'op' => '=', 'val' => $monitor['Id'] ) );
|
||||||
parseFilter( $filter );
|
parseFilter( $filter );
|
||||||
$counts[] = 'count(if(1'.$filter['sql'].",1,NULL)) as EventCount$j";
|
$counts[] = 'count(if(1'.$filter['sql'].",1,NULL)) AS EventCount$j, SUM(if(1".$filter['sql'].",DiskSpace,NULL)) As DiskSpace$j";
|
||||||
$monitor['eventCounts'][$j]['filter'] = $filter;
|
$monitor['eventCounts'][$j]['filter'] = $filter;
|
||||||
}
|
}
|
||||||
$sql = 'SELECt '.join($counts,', ').' from Events as E where MonitorId = ?';
|
$sql = 'SELECT '.join($counts,', ').' FROM Events as E where MonitorId = ?';
|
||||||
$counts = dbFetchOne( $sql, NULL, array($monitor['Id']) );
|
$counts = dbFetchOne( $sql, NULL, array($monitor['Id']) );
|
||||||
if ( $counts )
|
if ( $counts )
|
||||||
$displayMonitors[$i] = $monitor = array_merge( $monitor, $counts );
|
$displayMonitors[$i] = $monitor = array_merge( $monitor, $counts );
|
||||||
|
@ -241,6 +258,17 @@ echo htmlSelect( 'StorageFilter', array(''=>'All')+$StorageById, (isset($_SESSIO
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
<span class="StatusFilter"><label><?php echo translate('Status')?>:</label>
|
||||||
|
<?php
|
||||||
|
$status_options = array(
|
||||||
|
''=>'All',
|
||||||
|
'Unknown' => translate('Unknown'),
|
||||||
|
'NotRunning' => translate('NotRunning'),
|
||||||
|
'Running' => translate('Running'),
|
||||||
|
);
|
||||||
|
echo htmlSelect( 'StatusFilter', $status_options, ( isset($_SESSION['StatusFilter']) ? $_SESSION['StatusFilter'] : '' ), array('onchange'=>'changeFilter(this);') );
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
@ -331,7 +359,8 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
||||||
|
|
||||||
for ( $i = 0; $i < count($eventCounts); $i++ ) {
|
for ( $i = 0; $i < count($eventCounts); $i++ ) {
|
||||||
?>
|
?>
|
||||||
<td class="colEvents"><?php echo makePopupLink( '?view='.ZM_WEB_EVENTS_VIEW.'&page=1'.$monitor['eventCounts'][$i]['filter']['query'], $eventsWindow, ZM_WEB_EVENTS_VIEW, $monitor['EventCount'.$i], canView( 'Events' ) ) ?></td>
|
<td class="colEvents"><?php echo makePopupLink( '?view='.ZM_WEB_EVENTS_VIEW.'&page=1'.$monitor['eventCounts'][$i]['filter']['query'], $eventsWindow, ZM_WEB_EVENTS_VIEW,
|
||||||
|
$monitor['EventCount'.$i] . '<br/>' . human_filesize($monitor['DiskSpace'.$i]), canView( 'Events' ) ) ?></td>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
@ -356,7 +385,8 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
||||||
<td class="colId"><?php echo count($displayMonitors) ?></td>
|
<td class="colId"><?php echo count($displayMonitors) ?></td>
|
||||||
<td class="colLeftButtons" colspan="<?php echo $left_columns -1?>">
|
<td class="colLeftButtons" colspan="<?php echo $left_columns -1?>">
|
||||||
<input type="button" value="<?php echo translate('Refresh') ?>" onclick="location.reload(true);"/>
|
<input type="button" value="<?php echo translate('Refresh') ?>" onclick="location.reload(true);"/>
|
||||||
<input type="button" name="addBtn" value="<?php echo translate('AddNewMonitor') ?>" onclick="addMonitor( this )"/>
|
<input type="button" value="<?php echo translate('AddNewMonitor') ?>" onclick="location.href='index.php?view=add_monitors';"/>
|
||||||
|
<!--<input type="button" name="addBtn" value="<?php echo translate('AddNewMonitor') ?>" onclick="addMonitor( this )"/>-->
|
||||||
<!-- <?php echo makePopupButton( '?view=monitor', 'zmMonitor0', 'monitor', translate('AddNewMonitor'), (canEdit( 'Monitors' ) && !$user['MonitorIds']) ) ?> -->
|
<!-- <?php echo makePopupButton( '?view=monitor', 'zmMonitor0', 'monitor', translate('AddNewMonitor'), (canEdit( 'Monitors' ) && !$user['MonitorIds']) ) ?> -->
|
||||||
<?php echo makePopupButton( '?view=filter&filter[terms][0][attr]=DateTime&filter[terms][0][op]=%3c&filter[terms][0][val]=now', 'zmFilter', 'filter', translate('Filters'), canView( 'Events' ) ) ?>
|
<?php echo makePopupButton( '?view=filter&filter[terms][0][attr]=DateTime&filter[terms][0][op]=%3c&filter[terms][0][val]=now', 'zmFilter', 'filter', translate('Filters'), canView( 'Events' ) ) ?>
|
||||||
<input type="button" name="editBtn" value="<?php echo translate('Edit') ?>" onclick="editMonitor( this )" disabled="disabled"/>
|
<input type="button" name="editBtn" value="<?php echo translate('Edit') ?>" onclick="editMonitor( this )" disabled="disabled"/>
|
||||||
|
|
|
@ -36,13 +36,16 @@ if ( $user['MonitorIds'] ) {
|
||||||
}
|
}
|
||||||
$Monitor = $Event->Monitor();
|
$Monitor = $Event->Monitor();
|
||||||
|
|
||||||
if ( isset( $_REQUEST['rate'] ) )
|
if (isset($_REQUEST['rate'])) {
|
||||||
$rate = validInt($_REQUEST['rate']);
|
$rate = validInt($_REQUEST['rate']);
|
||||||
else
|
} else {
|
||||||
$rate = reScale(RATE_BASE, $Monitor->DefaultRate(), ZM_WEB_DEFAULT_RATE);
|
$rate = reScale(RATE_BASE, $Monitor->DefaultRate(), ZM_WEB_DEFAULT_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($_REQUEST['scale'])) {
|
if (isset($_REQUEST['scale'])) {
|
||||||
$scale = validInt($_REQUEST['scale']);
|
$scale = validInt($_REQUEST['scale']);
|
||||||
|
} else if (isset($_COOKIE['zmEventScaleAuto'])) { //If we're using scale to fit use it on all monitors
|
||||||
|
$scale = 'auto';
|
||||||
} else if (isset($_COOKIE['zmEventScale'.$Event->MonitorId()])) {
|
} else if (isset($_COOKIE['zmEventScale'.$Event->MonitorId()])) {
|
||||||
$scale = $_COOKIE['zmEventScale'.$Event->MonitorId()];
|
$scale = $_COOKIE['zmEventScale'.$Event->MonitorId()];
|
||||||
} else {
|
} else {
|
||||||
|
@ -153,20 +156,11 @@ if ( $Event->DefaultVideo() ) {
|
||||||
<div id="videoFeed">
|
<div id="videoFeed">
|
||||||
<video id="videoobj" class="video-js vjs-default-skin" width="<?php echo reScale( $Event->Width(), $scale ) ?>" height="<?php echo reScale( $Event->Height(), $scale ) ?>" data-setup='{ "controls": true, "playbackRates": [0.5, 1, 1.5, 2, 4, 8, 16, 32, 64, 128, 256], "autoplay": true, "preload": "auto", "plugins": { "zoomrotate": { "zoom": "<?php echo $Zoom ?>"}}}'>
|
<video id="videoobj" class="video-js vjs-default-skin" width="<?php echo reScale( $Event->Width(), $scale ) ?>" height="<?php echo reScale( $Event->Height(), $scale ) ?>" data-setup='{ "controls": true, "playbackRates": [0.5, 1, 1.5, 2, 4, 8, 16, 32, 64, 128, 256], "autoplay": true, "preload": "auto", "plugins": { "zoomrotate": { "zoom": "<?php echo $Zoom ?>"}}}'>
|
||||||
<source src="<?php echo $Event->getStreamSrc( array( 'mode'=>'mpeg','format'=>'h264' ) ); ?>" type="video/mp4">
|
<source src="<?php echo $Event->getStreamSrc( array( 'mode'=>'mpeg','format'=>'h264' ) ); ?>" type="video/mp4">
|
||||||
|
<track id="monitorCaption" kind="captions" label="English" srclang="en" src='data:plain/text;charset=utf-8,"WEBVTT\n\n 00:00:00.000 --> 00:00:01.000 ZoneMinder"' default>
|
||||||
Your browser does not support the video tag.
|
Your browser does not support the video tag.
|
||||||
</video>
|
</video>
|
||||||
</div>
|
</div>
|
||||||
<!--script>includeVideoJs();</script-->
|
<!--script>includeVideoJs();</script-->
|
||||||
<script type="text/javascript">
|
|
||||||
var LabelFormat = "<?php echo validJsStr($Monitor->LabelFormat())?>";
|
|
||||||
var monitorName = "<?php echo validJsStr($Monitor->Name())?>";
|
|
||||||
var duration = <?php echo $Event->Length() ?>, startTime = '<?php echo $Event->StartTime() ?>';
|
|
||||||
|
|
||||||
addVideoTimingTrack(document.getElementById('videoobj'), LabelFormat, monitorName, duration, startTime);
|
|
||||||
|
|
||||||
nearEventsQuery( eventData.Id );
|
|
||||||
vjsReplay(<?php echo (strtotime($Event->StartTime()) + $Event->Length())*1000 ?>);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<p id="dvrControls" class="dvrControls">
|
<p id="dvrControls" class="dvrControls">
|
||||||
<input type="button" value="<+" id="prevBtn" title="<?php echo translate('Prev') ?>" class="inactive" onclick="streamPrev( true );"/>
|
<input type="button" value="<+" id="prevBtn" title="<?php echo translate('Prev') ?>" class="inactive" onclick="streamPrev( true );"/>
|
||||||
|
@ -191,7 +185,7 @@ if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) {
|
||||||
}
|
}
|
||||||
} // end if stream method
|
} // end if stream method
|
||||||
?>
|
?>
|
||||||
<div id="alarmCueJpeg" class="alarmCue" style="width: <?php echo reScale($Event->Width(), $scale);?>px;"></div>
|
<div id="alarmCue" class="alarmCue" style="width: <?php echo reScale($Event->Width(), $scale);?>px;"></div>
|
||||||
<div id="progressBar" style="width: <?php echo reScale($Event->Width(), $scale);?>px;">
|
<div id="progressBar" style="width: <?php echo reScale($Event->Width(), $scale);?>px;">
|
||||||
<div class="progressBox" id="progressBox" title="" style="width: 0%;"></div>
|
<div class="progressBox" id="progressBox" title="" style="width: 0%;"></div>
|
||||||
</div><!--progressBar-->
|
</div><!--progressBar-->
|
||||||
|
|
|
@ -69,10 +69,14 @@ $attrTypes = array(
|
||||||
'Name' => translate('AttrName'),
|
'Name' => translate('AttrName'),
|
||||||
'Cause' => translate('AttrCause'),
|
'Cause' => translate('AttrCause'),
|
||||||
'Notes' => translate('AttrNotes'),
|
'Notes' => translate('AttrNotes'),
|
||||||
'DateTime' => translate('AttrDateTime'),
|
'StartDateTime' => translate('AttrStartDateTime'),
|
||||||
'Date' => translate('AttrDate'),
|
'StartDate' => translate('AttrStartDate'),
|
||||||
'Time' => translate('AttrTime'),
|
'StartTime' => translate('AttrStartTime'),
|
||||||
'Weekday' => translate('AttrWeekday'),
|
'StartWeekday' => translate('AttrStartWeekday'),
|
||||||
|
'EndDateTime' => translate('AttrEndDateTime'),
|
||||||
|
'EndDate' => translate('AttrEndDate'),
|
||||||
|
'EndTime' => translate('AttrEndTime'),
|
||||||
|
'EndWeekday' => translate('AttrEndWeekday'),
|
||||||
'Length' => translate('AttrDuration'),
|
'Length' => translate('AttrDuration'),
|
||||||
'Frames' => translate('AttrFrames'),
|
'Frames' => translate('AttrFrames'),
|
||||||
'AlarmFrames' => translate('AttrAlarmFrames'),
|
'AlarmFrames' => translate('AttrAlarmFrames'),
|
||||||
|
@ -80,8 +84,9 @@ $attrTypes = array(
|
||||||
'AvgScore' => translate('AttrAvgScore'),
|
'AvgScore' => translate('AttrAvgScore'),
|
||||||
'MaxScore' => translate('AttrMaxScore'),
|
'MaxScore' => translate('AttrMaxScore'),
|
||||||
'Archived' => translate('AttrArchiveStatus'),
|
'Archived' => translate('AttrArchiveStatus'),
|
||||||
'DiskPercent' => translate('AttrDiskPercent'),
|
|
||||||
'DiskBlocks' => translate('AttrDiskBlocks'),
|
'DiskBlocks' => translate('AttrDiskBlocks'),
|
||||||
|
'DiskPercent' => translate('AttrDiskPercent'),
|
||||||
|
'DiskSpace' => translate('AttrDiskSpace'),
|
||||||
'SystemLoad' => translate('AttrSystemLoad'),
|
'SystemLoad' => translate('AttrSystemLoad'),
|
||||||
'StorageId' => translate('AttrStorageArea'),
|
'StorageId' => translate('AttrStorageArea'),
|
||||||
'ServerId' => translate('AttrServer'),
|
'ServerId' => translate('AttrServer'),
|
||||||
|
@ -99,6 +104,8 @@ $opTypes = array(
|
||||||
'!~' => translate('OpNotMatches'),
|
'!~' => translate('OpNotMatches'),
|
||||||
'=[]' => translate('OpIn'),
|
'=[]' => translate('OpIn'),
|
||||||
'![]' => translate('OpNotIn'),
|
'![]' => translate('OpNotIn'),
|
||||||
|
'IS' => translate('OpIs'),
|
||||||
|
'IS NOT' => translate('OpIsNot'),
|
||||||
);
|
);
|
||||||
|
|
||||||
$archiveTypes = array(
|
$archiveTypes = array(
|
||||||
|
@ -300,9 +307,10 @@ $sort_fields = array(
|
||||||
'Id' => translate('AttrId'),
|
'Id' => translate('AttrId'),
|
||||||
'Name' => translate('AttrName'),
|
'Name' => translate('AttrName'),
|
||||||
'Cause' => translate('AttrCause'),
|
'Cause' => translate('AttrCause'),
|
||||||
|
'DiskSpace' => translate('AttrDiskSpace'),
|
||||||
'Notes' => translate('AttrNotes'),
|
'Notes' => translate('AttrNotes'),
|
||||||
'MonitorName' => translate('AttrMonitorName'),
|
'MonitorName' => translate('AttrMonitorName'),
|
||||||
'DateTime' => translate('AttrDateTime'),
|
'StartDateTime' => translate('AttrStartDateTime'),
|
||||||
'Length' => translate('AttrDuration'),
|
'Length' => translate('AttrDuration'),
|
||||||
'Frames' => translate('AttrFrames'),
|
'Frames' => translate('AttrFrames'),
|
||||||
'AlarmFrames' => translate('AttrAlarmFrames'),
|
'AlarmFrames' => translate('AttrAlarmFrames'),
|
||||||
|
@ -332,6 +340,9 @@ echo htmlSelect( 'filter[Query][sort_asc]', $sort_dirns, $filter->sort_asc() );
|
||||||
<label><?php echo translate('FilterArchiveEvents') ?></label>
|
<label><?php echo translate('FilterArchiveEvents') ?></label>
|
||||||
<input type="checkbox" name="filter[AutoArchive]" value="1"<?php if ( !empty($filter->AutoArchive()) ) { ?> checked="checked"<?php } ?> onclick="updateButtons( this )"/>
|
<input type="checkbox" name="filter[AutoArchive]" value="1"<?php if ( !empty($filter->AutoArchive()) ) { ?> checked="checked"<?php } ?> onclick="updateButtons( this )"/>
|
||||||
</p>
|
</p>
|
||||||
|
<p><label><?php echo translate('FilterUpdateDiskSpace') ?></label>
|
||||||
|
<input type="checkbox" name="filter[UpdateDiskSpace]" value="1"<?php echo empty($filter->UpdateDiskSpace()) ? '' : ' checked="checked"' ?> onclick="updateButtons(this);"/>
|
||||||
|
</p>
|
||||||
<?php
|
<?php
|
||||||
if ( ZM_OPT_FFMPEG ) {
|
if ( ZM_OPT_FFMPEG ) {
|
||||||
?>
|
?>
|
||||||
|
@ -387,7 +398,7 @@ if ( ZM_OPT_MESSAGE ) {
|
||||||
</div>
|
</div>
|
||||||
<hr/>
|
<hr/>
|
||||||
<div id="contentButtons">
|
<div id="contentButtons">
|
||||||
<input type="submit" value="<?php echo translate('Submit') ?>" onclick="submitToEvents( this );"/>
|
<input type="submit" value="<?php echo translate('ListMatches') ?>" onclick="submitToEvents( this );"/>
|
||||||
<input type="button" name="executeButton" id="executeButton" value="<?php echo translate('Execute') ?>" onclick="executeFilter( this );"/>
|
<input type="button" name="executeButton" id="executeButton" value="<?php echo translate('Execute') ?>" onclick="executeFilter( this );"/>
|
||||||
<?php
|
<?php
|
||||||
if ( canEdit( 'Events' ) ) {
|
if ( canEdit( 'Events' ) ) {
|
||||||
|
|
|
@ -13,7 +13,7 @@ function setButtonStates( element ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$(element).closest("tr").toggleClass("danger");
|
$(element).closest("tr").toggleClass("danger");
|
||||||
form.editBtn.disabled = (checked!=1);
|
form.editBtn.disabled = checked ? false : true;
|
||||||
form.addBtn.value = (checked==1) ? jsTranslatedCloneText:jsTranslatedAddText;
|
form.addBtn.value = (checked==1) ? jsTranslatedCloneText:jsTranslatedAddText;
|
||||||
|
|
||||||
form.deleteBtn.disabled = (checked==0);
|
form.deleteBtn.disabled = (checked==0);
|
||||||
|
@ -40,18 +40,23 @@ function addMonitor( element) {
|
||||||
|
|
||||||
function editMonitor( element ) {
|
function editMonitor( element ) {
|
||||||
var form = element.form;
|
var form = element.form;
|
||||||
|
var monitorIds = Array();
|
||||||
|
|
||||||
for ( var i = 0; i < form.elements.length; i++ ) {
|
for ( var i = 0; i < form.elements.length; i++ ) {
|
||||||
if ( form.elements[i].type == "checkbox" ) {
|
if ( form.elements[i].type == "checkbox" ) {
|
||||||
if ( form.elements[i].checked ) {
|
if ( form.elements[i].checked ) {
|
||||||
var monitorId = form.elements[i].value;
|
monitorIds.push( form.elements[i].value );
|
||||||
createPopup( '?view=monitor&mid='+monitorId, 'zmMonitor'+monitorId, 'monitor' );
|
//form.elements[i].checked = false;
|
||||||
form.elements[i].checked = false;
|
//setButtonStates( form.elements[i] );
|
||||||
setButtonStates( form.elements[i] );
|
|
||||||
//$(form.elements[i]).getParent( 'tr' ).removeClass( 'highlight' );
|
//$(form.elements[i]).getParent( 'tr' ).removeClass( 'highlight' );
|
||||||
break;
|
//break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} // end foreach checkboxes
|
||||||
|
if ( monitorIds.length == 1 )
|
||||||
|
createPopup( '?view=monitor&mid='+monitorIds[0], 'zmMonitor'+monitorIds[0], 'monitor' );
|
||||||
|
else if ( monitorIds.length > 1 )
|
||||||
|
createPopup( '?view=monitors&'+(monitorIds.map(function(mid){return 'mids[]='+mid;}).join('&')), 'zmMonitors', 'monitors' );
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteMonitor( element ) {
|
function deleteMonitor( element ) {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
var vid = null;
|
var vid = null;
|
||||||
|
|
||||||
function vjsReplay(endTime) {
|
function vjsReplay() {
|
||||||
var video = videojs('videoobj').ready(function(){
|
vid.ready(function(){
|
||||||
var player = this;
|
var player = this;
|
||||||
player.on('ended', function() {
|
player.on('ended', function() {
|
||||||
|
var endTime = (Date.parse(eventData.EndTime)).getTime();
|
||||||
switch(replayMode.value) {
|
switch(replayMode.value) {
|
||||||
case 'none':
|
case 'none':
|
||||||
break;
|
break;
|
||||||
|
@ -12,19 +13,23 @@ function vjsReplay(endTime) {
|
||||||
break;
|
break;
|
||||||
case 'all':
|
case 'all':
|
||||||
if (nextEventId == 0) {
|
if (nextEventId == 0) {
|
||||||
$j("#videoobj").html('<p class="vjsMessage">No more events</p>');
|
let overLaid = $j("#videoobj");
|
||||||
|
overLaid.append('<p class="vjsMessage" style="height: '+overLaid.height()+'px; line-height: '+overLaid.height()+'px;">No more events</p>');
|
||||||
} else {
|
} else {
|
||||||
var nextStartTime = nextEventStartTime.getTime(); //nextEventStartTime.getTime() is a mootools workaround, highjacks Date.parse
|
var nextStartTime = nextEventStartTime.getTime(); //nextEventStartTime.getTime() is a mootools workaround, highjacks Date.parse
|
||||||
if (nextStartTime <= endTime) {
|
if (nextStartTime <= endTime) {
|
||||||
streamNext( true );
|
streamNext( true );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$j("#videoobj").html('<p class="vjsMessage"></p>');
|
let overLaid = $j("#videoobj");
|
||||||
|
vid.pause();
|
||||||
|
overLaid.append('<p class="vjsMessage" style="height: '+overLaid.height()+'px; line-height: '+overLaid.height()+'px;"></p>');
|
||||||
var gapDuration = (new Date().getTime()) + (nextStartTime - endTime);
|
var gapDuration = (new Date().getTime()) + (nextStartTime - endTime);
|
||||||
|
let messageP = $j(".vjsMessage");
|
||||||
var x = setInterval(function() {
|
var x = setInterval(function() {
|
||||||
var now = new Date().getTime();
|
var now = new Date().getTime();
|
||||||
var remainder = new Date(Math.round(gapDuration - now)).toISOString().substr(11,8);
|
var remainder = new Date(Math.round(gapDuration - now)).toISOString().substr(11,8);
|
||||||
$j(".vjsMessage").html(remainder + ' to next event.');
|
messageP.html(remainder + ' to next event.');
|
||||||
if (remainder < 0) {
|
if (remainder < 0) {
|
||||||
clearInterval(x);
|
clearInterval(x);
|
||||||
streamNext( true );
|
streamNext( true );
|
||||||
|
@ -51,17 +56,12 @@ function initialAlarmCues (eventId) {
|
||||||
function setAlarmCues (data) {
|
function setAlarmCues (data) {
|
||||||
cueFrames = data.event.Frame;
|
cueFrames = data.event.Frame;
|
||||||
alarmSpans = renderAlarmCues();
|
alarmSpans = renderAlarmCues();
|
||||||
if ( vid ) {
|
$j(".alarmCue").html(alarmSpans);
|
||||||
$j(".vjs-progress-control").append('<div class="alarmCue">' + alarmSpans + '</div>');
|
|
||||||
$j(".vjs-control-bar").addClass("vjs-zm");
|
|
||||||
} else {
|
|
||||||
$j("#alarmCueJpeg").html(alarmSpans);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderAlarmCues () {
|
function renderAlarmCues () {
|
||||||
if (cueFrames) {
|
if (cueFrames) {
|
||||||
var cueRatio = (vid ? $j("#videoobj").width() : $j("#evtStream").width()) / (cueFrames[cueFrames.length - 1].Delta * 100);//use videojs width or nph-zms width
|
var cueRatio = (vid ? $j("#videoobj").width() : $j("#evtStream").width()) / (cueFrames[cueFrames.length - 1].Delta * 100);//use videojs width or zms width
|
||||||
var minAlarm = Math.ceil(1/cueRatio);
|
var minAlarm = Math.ceil(1/cueRatio);
|
||||||
var spanTimeStart = 0;
|
var spanTimeStart = 0;
|
||||||
var spanTimeEnd = 0;
|
var spanTimeEnd = 0;
|
||||||
|
@ -118,6 +118,7 @@ function renderAlarmCues () {
|
||||||
spanTime = spanTimeEnd - spanTimeStart;
|
spanTime = spanTimeEnd - spanTimeStart;
|
||||||
alarmed = 0;
|
alarmed = 0;
|
||||||
pix = Math.round(cueRatio * spanTime);
|
pix = Math.round(cueRatio * spanTime);
|
||||||
|
if (pixSkew >= .5 || pixSkew <= -.5) pix += Math.round(pixSkew);
|
||||||
alarmHtml += '<span class="alarmCue" style="width: ' + pix + 'px;"></span>';
|
alarmHtml += '<span class="alarmCue" style="width: ' + pix + 'px;"></span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,27 +135,54 @@ function setButtonState( element, butClass ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var resizeTimer;
|
||||||
|
|
||||||
|
function endOfResize(e) {
|
||||||
|
clearTimeout(resizeTimer);
|
||||||
|
resizeTimer = setTimeout(changeScale, 250);
|
||||||
|
}
|
||||||
|
|
||||||
|
function scaleToFit () {
|
||||||
|
$j(window).on('resize', endOfResize) //set delayed scaling when Scale to Fit is selected
|
||||||
|
let ratio = eventData.Width/eventData.Height;
|
||||||
|
let container = $j('#content');
|
||||||
|
let feed = $j(vid ? '#videoobj' : '#evtStream');
|
||||||
|
let viewPort = $j(window);
|
||||||
|
let newHeight = viewPort.height() - (container.outerHeight(true) - feed.outerHeight(true));
|
||||||
|
let newWidth = ratio * newHeight;
|
||||||
|
if (newWidth > container.innerWidth()) {
|
||||||
|
newWidth = container.innerWidth();
|
||||||
|
newHeight = newWidth / ratio;
|
||||||
|
}
|
||||||
|
return {width: Math.floor(newWidth), height: Math.floor(newHeight)};
|
||||||
|
}
|
||||||
|
|
||||||
function changeScale() {
|
function changeScale() {
|
||||||
var scale = $('scale').get('value');
|
let scale = $j('#scale').val();
|
||||||
var baseWidth = eventData.Width;
|
if (scale == "auto") {
|
||||||
var baseHeight = eventData.Height;
|
let newSize = scaleToFit();
|
||||||
var newWidth = ( baseWidth * scale ) / SCALE_BASE;
|
var newWidth = newSize.width;
|
||||||
var newHeight = ( baseHeight * scale ) / SCALE_BASE;
|
var newHeight = newSize.height;
|
||||||
if ( vid ) {
|
|
||||||
// Using video.js
|
|
||||||
$j("#videoobj").width(newWidth);
|
|
||||||
$j("#videoobj").height(newHeight);
|
|
||||||
$j("div.alarmCue").html(renderAlarmCues());//just re-render alarmCues. skip ajax call
|
|
||||||
Cookie.write( 'zmEventScale'+eventData.MonitorId, scale, { duration: 10*365 } );
|
|
||||||
} else {
|
} else {
|
||||||
streamScale( scale );
|
$j(window).off('resize', endOfResize); //remove resize handler when Scale to Fit is not active
|
||||||
var streamImg = document.getElementById('evtStream');
|
var newWidth = eventData.Width * scale / SCALE_BASE;
|
||||||
streamImg.style.width = newWidth + "px";
|
var newHeight = eventData.Height * scale / SCALE_BASE;
|
||||||
streamImg.style.height = newHeight + "px";
|
}
|
||||||
$j("#alarmCueJpeg").width(newWidth);
|
let alarmCue = $j('div.alarmCue');
|
||||||
|
let eventViewer = $j(vid ? '#videoobj' : '#evtStream')
|
||||||
|
eventViewer.width(newWidth);
|
||||||
|
eventViewer.height(newHeight);
|
||||||
|
if ( !vid ) { // zms needs extra sizing
|
||||||
|
streamScale(scale == "auto" ? Math.round(newWidth / eventData.Width * SCALE_BASE) : scale);
|
||||||
|
alarmCue.width(newWidth);
|
||||||
drawProgressBar();
|
drawProgressBar();
|
||||||
$j("#alarmCueJpeg").html(renderAlarmCues());
|
}
|
||||||
|
alarmCue.html(renderAlarmCues());//just re-render alarmCues. skip ajax call
|
||||||
|
if (scale == "auto") {
|
||||||
|
Cookie.write('zmEventScaleAuto', 'auto', {duration: 10*365});
|
||||||
|
}else{
|
||||||
Cookie.write('zmEventScale'+eventData.MonitorId, scale, {duration: 10*365});
|
Cookie.write('zmEventScale'+eventData.MonitorId, scale, {duration: 10*365});
|
||||||
|
Cookie.dispose('zmEventScaleAuto');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +204,7 @@ var zmsBroke = false; //Use alternate navigation if zms has crashed
|
||||||
function getCmdResponse( respObj, respText ) {
|
function getCmdResponse( respObj, respText ) {
|
||||||
if ( checkStreamForErrors( "getCmdResponse", respObj ) ) {
|
if ( checkStreamForErrors( "getCmdResponse", respObj ) ) {
|
||||||
console.log('Got an error from getCmdResponse');
|
console.log('Got an error from getCmdResponse');
|
||||||
var zmsBroke = true;
|
zmsBroke = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,7 +329,11 @@ function streamFastRev( action ) {
|
||||||
|
|
||||||
function streamPrev(action) {
|
function streamPrev(action) {
|
||||||
if (action) {
|
if (action) {
|
||||||
if (vid || PrevEventDefVideoPath.indexOf("view_video") >=0 || $j("#vjsMessage").length || zmsBroke) { //handles this or prev being video.js, or end of events
|
$j(".vjsMessage").remove();
|
||||||
|
if (vid && PrevEventDefVideoPath.indexOf("view_video") > 0) {
|
||||||
|
CurEventDefVideoPath = PrevEventDefVideoPath;
|
||||||
|
eventQuery(prevEventId);
|
||||||
|
} else if (zmsBroke || (vid && PrevEventDefVideoPath.indexOf("view_video") < 0) || $j("#vjsMessage").length || PrevEventDefVideoPath.indexOf("view_video") > 0) {//zms broke, leaving videojs, last event, moving to videojs
|
||||||
location.replace(thisUrl + '?view=event&eid=' + prevEventId + filterQuery + sortQuery);
|
location.replace(thisUrl + '?view=event&eid=' + prevEventId + filterQuery + sortQuery);
|
||||||
} else {
|
} else {
|
||||||
streamReq.send(streamParms+"&command="+CMD_PREV);
|
streamReq.send(streamParms+"&command="+CMD_PREV);
|
||||||
|
@ -311,10 +343,19 @@ function streamPrev(action) {
|
||||||
|
|
||||||
function streamNext(action) {
|
function streamNext(action) {
|
||||||
if (action) {
|
if (action) {
|
||||||
|
$j(".vjsMessage").remove();//This shouldn't happen
|
||||||
if (nextEventId == 0) { //handles deleting last event.
|
if (nextEventId == 0) { //handles deleting last event.
|
||||||
let replaceStream = $j(vid ? "#videoobj" : "#evtStream");
|
vid ? vid.pause() : streamPause();
|
||||||
replaceStream.replaceWith('<p class="vjsMessage" style="width:' + replaceStream.css("width") + '; height: ' + replaceStream.css("height") + ';line-height: ' + replaceStream.css("height") + ';">No more events</p>');
|
let hideContainer = $j( vid ? "#eventVideo" : "#imageFeed");
|
||||||
} else if (vid || NextEventDefVideoPath.indexOf("view_video") >=0 || zmsBroke) { //handles current or next switch to video.js
|
let hideStream = $j(vid ? "#videoobj" : "#evtStream").height() + (vid ? 0 :$j("#progressBar").height());
|
||||||
|
hideContainer.prepend('<p class="vjsMessage" style="height: ' + hideStream + 'px; line-height: ' + hideStream + 'px;">No more events</p>');
|
||||||
|
if (vid == null) zmsBroke = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (vid && NextEventDefVideoPath.indexOf("view_video") > 0) { //on and staying with videojs
|
||||||
|
CurEventDefVideoPath = NextEventDefVideoPath;
|
||||||
|
eventQuery(nextEventId);
|
||||||
|
} else if (zmsBroke || (vid && NextEventDefVideoPath.indexOf("view_video") < 0) || NextEventDefVideoPath.indexOf("view_video") > 0) {//reload zms, leaving vjs, moving to vjs
|
||||||
location.replace(thisUrl + '?view=event&eid=' + nextEventId + filterQuery + sortQuery);
|
location.replace(thisUrl + '?view=event&eid=' + nextEventId + filterQuery + sortQuery);
|
||||||
} else {
|
} else {
|
||||||
streamReq.send(streamParms+"&command="+CMD_NEXT);
|
streamReq.send(streamParms+"&command="+CMD_NEXT);
|
||||||
|
@ -348,6 +389,7 @@ function streamQuery() {
|
||||||
|
|
||||||
var slider = null;
|
var slider = null;
|
||||||
var scroll = null;
|
var scroll = null;
|
||||||
|
var CurEventDefVideoPath = null;
|
||||||
|
|
||||||
function getEventResponse( respObj, respText ) {
|
function getEventResponse( respObj, respText ) {
|
||||||
if ( checkStreamForErrors( "getEventResponse", respObj ) ) {
|
if ( checkStreamForErrors( "getEventResponse", respObj ) ) {
|
||||||
|
@ -374,7 +416,7 @@ function getEventResponse( respObj, respText ) {
|
||||||
$('dataFrames').set( 'text', eventData.Frames+"/"+eventData.AlarmFrames );
|
$('dataFrames').set( 'text', eventData.Frames+"/"+eventData.AlarmFrames );
|
||||||
$('dataScore').set( 'text', eventData.TotScore+"/"+eventData.AvgScore+"/"+eventData.MaxScore );
|
$('dataScore').set( 'text', eventData.TotScore+"/"+eventData.AvgScore+"/"+eventData.MaxScore );
|
||||||
$('eventName').setProperty( 'value', eventData.Name );
|
$('eventName').setProperty( 'value', eventData.Name );
|
||||||
|
history.replaceState(null, null, '?view=event&eid=' + eventData.Id + filterQuery + sortQuery);//if popup removed, check if this allows forward
|
||||||
if ( canEditEvents ) {
|
if ( canEditEvents ) {
|
||||||
if ( parseInt(eventData.Archived) ) {
|
if ( parseInt(eventData.Archived) ) {
|
||||||
$('archiveEvent').addClass( 'hidden' );
|
$('archiveEvent').addClass( 'hidden' );
|
||||||
|
@ -387,7 +429,14 @@ function getEventResponse( respObj, respText ) {
|
||||||
// Technically, events can be different sizes, so may need to update the size of the image, but it might be better to have it stay scaled...
|
// Technically, events can be different sizes, so may need to update the size of the image, but it might be better to have it stay scaled...
|
||||||
//var eventImg = $('eventImage');
|
//var eventImg = $('eventImage');
|
||||||
//eventImg.setStyles( { 'width': eventData.width, 'height': eventData.height } );
|
//eventImg.setStyles( { 'width': eventData.width, 'height': eventData.height } );
|
||||||
|
if (vid && CurEventDefVideoPath) {
|
||||||
|
vid.src({type: 'video/mp4', src: CurEventDefVideoPath}); //Currently mp4 is all we use
|
||||||
|
initialAlarmCues(eventData.Id);//ajax and render, new event
|
||||||
|
addVideoTimingTrack(vid, LabelFormat, eventData.MonitorName, eventData.Length, eventData.StartTime);
|
||||||
|
CurEventDefVideoPath = null;
|
||||||
|
} else {
|
||||||
drawProgressBar();
|
drawProgressBar();
|
||||||
|
}
|
||||||
nearEventsQuery( eventData.Id );
|
nearEventsQuery( eventData.Id );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,6 +742,7 @@ function getActResponse( respObj, respText ) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( respObj.refreshParent )
|
if ( respObj.refreshParent )
|
||||||
|
if (refreshParent == false) refreshParent = true; //Bypass filter window redirect fix.
|
||||||
refreshParentWindow();
|
refreshParentWindow();
|
||||||
|
|
||||||
if ( respObj.refreshEvent )
|
if ( respObj.refreshEvent )
|
||||||
|
@ -793,7 +843,7 @@ function videoEvent() {
|
||||||
|
|
||||||
// Called on each event load because each event can be a different width
|
// Called on each event load because each event can be a different width
|
||||||
function drawProgressBar() {
|
function drawProgressBar() {
|
||||||
var barWidth = (eventData.Width * $j('#scale').val()) / SCALE_BASE;
|
let barWidth = $j('#evtStream').width();
|
||||||
$j('#progressBar').css( 'width', barWidth );
|
$j('#progressBar').css( 'width', barWidth );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -807,7 +857,7 @@ function updateProgressBar() {
|
||||||
} // end function updateProgressBar()
|
} // end function updateProgressBar()
|
||||||
|
|
||||||
// Handles seeking when clicking on the progress bar.
|
// Handles seeking when clicking on the progress bar.
|
||||||
function progressBarSeek (){
|
function progressBarNav (){
|
||||||
$j('#progressBar').click(function(e){
|
$j('#progressBar').click(function(e){
|
||||||
var x = e.pageX - $j(this).offset().left;
|
var x = e.pageX - $j(this).offset().left;
|
||||||
var seekTime = (x / $j('#progressBar').width()) * parseFloat(eventData.Length);
|
var seekTime = (x / $j('#progressBar').width()) * parseFloat(eventData.Length);
|
||||||
|
@ -924,9 +974,13 @@ function setupListener() {
|
||||||
|
|
||||||
function initPage() {
|
function initPage() {
|
||||||
//FIXME prevent blocking...not sure what is happening or best way to unblock
|
//FIXME prevent blocking...not sure what is happening or best way to unblock
|
||||||
if ( $('videoobj') ) {
|
if ($j('#videoobj').length) {
|
||||||
vid = videojs("videoobj");
|
vid = videojs("videoobj");
|
||||||
initialAlarmCues(eventData.Id); //call ajax+renderAlarmCues after videojs is. should be only call to initialAlarmCues on vjs streams
|
addVideoTimingTrack(vid, LabelFormat, eventData.MonitorName, eventData.Length, eventData.StartTime);
|
||||||
|
$j(".vjs-progress-control").append('<div class="alarmCue"></div>');//add a place for videojs only on first load
|
||||||
|
nearEventsQuery(eventData.Id);
|
||||||
|
initialAlarmCues(eventData.Id); //call ajax+renderAlarmCues after videojs is initialized
|
||||||
|
vjsReplay();
|
||||||
}
|
}
|
||||||
if (vid) {
|
if (vid) {
|
||||||
/*
|
/*
|
||||||
|
@ -947,10 +1001,10 @@ function initPage() {
|
||||||
window.videoobj.load();
|
window.videoobj.load();
|
||||||
streamPlay(); */
|
streamPlay(); */
|
||||||
} else {
|
} else {
|
||||||
progressBarSeek ();
|
progressBarNav ();
|
||||||
streamCmdTimer = streamQuery.delay( 250 );
|
streamCmdTimer = streamQuery.delay( 250 );
|
||||||
eventQuery.pass( eventData.Id ).delay( 500 );
|
eventQuery.pass( eventData.Id ).delay( 500 );
|
||||||
initialAlarmCues(eventData.Id); //call ajax+renderAlarmCues for nph-zms.
|
initialAlarmCues(eventData.Id); //call ajax+renderAlarmCues for zms.
|
||||||
|
|
||||||
if ( canStreamNative ) {
|
if ( canStreamNative ) {
|
||||||
var streamImg = $('imageFeed').getElement('img');
|
var streamImg = $('imageFeed').getElement('img');
|
||||||
|
@ -959,6 +1013,7 @@ function initPage() {
|
||||||
$(streamImg).addEvent( 'click', function( event ) { handleClick( event ); } );
|
$(streamImg).addEvent( 'click', function( event ) { handleClick( event ); } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (scale == "auto") changeScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kick everything off
|
// Kick everything off
|
||||||
|
|
|
@ -30,13 +30,18 @@ var eventData = {
|
||||||
MonitorId: '<?php echo $Event->MonitorId() ?>',
|
MonitorId: '<?php echo $Event->MonitorId() ?>',
|
||||||
Width: '<?php echo $Event->Width() ?>',
|
Width: '<?php echo $Event->Width() ?>',
|
||||||
Height: '<?php echo $Event->Height() ?>',
|
Height: '<?php echo $Event->Height() ?>',
|
||||||
Length: '<?php echo $Event->Length() ?>'
|
Length: '<?php echo $Event->Length() ?>',
|
||||||
|
StartTime: '<?php echo $Event->StartTime() ?>',
|
||||||
|
EndTime: '<?php echo $Event->EndTime() ?>',
|
||||||
|
MonitorName: '<?php echo $Monitor->Name() ?>'
|
||||||
};
|
};
|
||||||
|
|
||||||
var filterQuery = '<?php echo isset($filterQuery)?validJsStr(htmlspecialchars_decode($filterQuery)):'' ?>';
|
var filterQuery = '<?php echo isset($filterQuery)?validJsStr(htmlspecialchars_decode($filterQuery)):'' ?>';
|
||||||
var sortQuery = '<?php echo isset($sortQuery)?validJsStr(htmlspecialchars_decode($sortQuery)):'' ?>';
|
var sortQuery = '<?php echo isset($sortQuery)?validJsStr(htmlspecialchars_decode($sortQuery)):'' ?>';
|
||||||
|
|
||||||
var scale = <?php echo $scale ?>;
|
var scale = "<?php echo $scale ?>";
|
||||||
|
var LabelFormat = "<?php echo validJsStr($Monitor->LabelFormat())?>";
|
||||||
|
|
||||||
var canEditEvents = <?php echo canEdit( 'Events' )?'true':'false' ?>;
|
var canEditEvents = <?php echo canEdit( 'Events' )?'true':'false' ?>;
|
||||||
var streamTimeout = <?php echo 1000*ZM_WEB_REFRESH_STATUS ?>;
|
var streamTimeout = <?php echo 1000*ZM_WEB_REFRESH_STATUS ?>;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ function updateButtons( element ) {
|
||||||
canExecute = true;
|
canExecute = true;
|
||||||
else if ( form.elements['filter[AutoDelete]'].checked )
|
else if ( form.elements['filter[AutoDelete]'].checked )
|
||||||
canExecute = true;
|
canExecute = true;
|
||||||
|
else if ( form.elements['filter[UpdateDiskSpace]'].checked )
|
||||||
|
canExecute = true;
|
||||||
form.elements['executeButton'].disabled = !canExecute;
|
form.elements['executeButton'].disabled = !canExecute;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ function validateForm( form ) {
|
||||||
else if ( form.elements.mid.value == 0 && monitorNames[form.elements['newMonitor[Name]'].value] )
|
else if ( form.elements.mid.value == 0 && monitorNames[form.elements['newMonitor[Name]'].value] )
|
||||||
errors[errors.length] = "<?php echo translate('DuplicateMonitorName') ?>";
|
errors[errors.length] = "<?php echo translate('DuplicateMonitorName') ?>";
|
||||||
|
|
||||||
if ( form.elements['newMonitor[AnalysisFPS]'].value && !(parseFloat(form.elements['newMonitor[AnalysisFPS]'].value) > 0 ) )
|
if ( form.elements['newMonitor[AnalysisFPSLimit]'].value && !(parseFloat(form.elements['newMonitor[AnalysisFPSLimit]'].value) > 0 ) )
|
||||||
errors[errors.length] = "<?php echo translate('BadAnalysisFPS') ?>";
|
errors[errors.length] = "<?php echo translate('BadAnalysisFPS') ?>";
|
||||||
if ( form.elements['newMonitor[MaxFPS]'].value && !(parseFloat(form.elements['newMonitor[MaxFPS]'].value) > 0 ) )
|
if ( form.elements['newMonitor[MaxFPS]'].value && !(parseFloat(form.elements['newMonitor[MaxFPS]'].value) > 0 ) )
|
||||||
errors[errors.length] = "<?php echo translate('BadMaxFPS') ?>";
|
errors[errors.length] = "<?php echo translate('BadMaxFPS') ?>";
|
||||||
|
|
|
@ -10,8 +10,6 @@ function Monitor( monitorData ) {
|
||||||
this.streamCmdParms = "view=request&request=stream&connkey="+this.connKey;
|
this.streamCmdParms = "view=request&request=stream&connkey="+this.connKey;
|
||||||
if ( auth_hash )
|
if ( auth_hash )
|
||||||
this.streamCmdParms += '&auth='+auth_hash;
|
this.streamCmdParms += '&auth='+auth_hash;
|
||||||
else
|
|
||||||
console.log("No auth_hash");
|
|
||||||
this.streamCmdTimer = null;
|
this.streamCmdTimer = null;
|
||||||
|
|
||||||
this.start = function( delay ) {
|
this.start = function( delay ) {
|
||||||
|
@ -89,8 +87,12 @@ function Monitor( monitorData ) {
|
||||||
} else {
|
} else {
|
||||||
console.error( respObj.message );
|
console.error( respObj.message );
|
||||||
// Try to reload the image stream.
|
// Try to reload the image stream.
|
||||||
if ( stream )
|
if ( stream ) {
|
||||||
|
console.log('Reloading stream: ' + stream.src );
|
||||||
stream.src = stream.src.replace(/rand=\d+/i, 'rand='+Math.floor((Math.random() * 1000000) ));
|
stream.src = stream.src.replace(/rand=\d+/i, 'rand='+Math.floor((Math.random() * 1000000) ));
|
||||||
|
} else {
|
||||||
|
console.log( 'No stream to reload?' );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var streamCmdTimeout = statusRefreshTimeout;
|
var streamCmdTimeout = statusRefreshTimeout;
|
||||||
if ( this.alarmState == STATE_ALARM || this.alarmState == STATE_ALERT )
|
if ( this.alarmState == STATE_ALARM || this.alarmState == STATE_ALERT )
|
||||||
|
@ -112,13 +114,45 @@ function Monitor( monitorData ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectLayout( element ) {
|
function selectLayout( element ) {
|
||||||
layout = $(element).get('value')
|
layout = $(element).get('value');
|
||||||
var cssFile = skinPath+'/css/'+Cookie.read('zmCSS')+'/views/'+layout;
|
|
||||||
if ( $('dynamicStyles') )
|
if ( layout_id = parseInt(layout) ) {
|
||||||
$('dynamicStyles').destroy();
|
layout = layouts[layout];
|
||||||
new Asset.css( cssFile, { id: 'dynamicStyles' } );
|
console.log("Have layout # " + layout_id);
|
||||||
Cookie.write( 'zmMontageLayout', layout, { duration: 10*365 } );
|
|
||||||
if ( layout != 'montage_freeform.css' ) {
|
for ( var i = 0; i < monitors.length; i++ ) {
|
||||||
|
monitor = monitors[i];
|
||||||
|
// Need to clear the current positioning, and apply the new
|
||||||
|
|
||||||
|
monitor_frame = $j('#monitorFrame'+monitor.id);
|
||||||
|
if ( ! monitor_frame ) {
|
||||||
|
console.log("Error finding frame for " + monitor.id );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply default layout options, like float left
|
||||||
|
if ( layout.default ) {
|
||||||
|
styles = layout.default;
|
||||||
|
for ( style in styles ) {
|
||||||
|
console.log("applying " + style + ': ' + styles[style]);
|
||||||
|
monitor_frame.css(style, styles[style]);
|
||||||
|
}
|
||||||
|
} // end if default styles
|
||||||
|
|
||||||
|
if ( layout[monitor.id] ) {
|
||||||
|
styles = layout[monitor.id];
|
||||||
|
for ( style in styles ) {
|
||||||
|
console.log("applying " + style + ': ' + styles[style]);
|
||||||
|
monitor_frame.css(style, styles[style]);
|
||||||
|
}
|
||||||
|
} // end if specific monitor style
|
||||||
|
} // end foreach monitor
|
||||||
|
} // end if a stored layout
|
||||||
|
if ( ! layout ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Cookie.write( 'zmMontageLayout', layout_id, { duration: 10*365 } );
|
||||||
|
if ( layout_id != 1 ) { // 'montage_freeform.css' ) {
|
||||||
Cookie.write( 'zmMontageScale', '', { duration: 10*365 } );
|
Cookie.write( 'zmMontageScale', '', { duration: 10*365 } );
|
||||||
$('scale').set('value', '' );
|
$('scale').set('value', '' );
|
||||||
$('width').set('value', '');
|
$('width').set('value', '');
|
||||||
|
@ -152,6 +186,17 @@ function changeSize() {
|
||||||
|
|
||||||
for ( var x = 0; x < monitors.length; x++ ) {
|
for ( var x = 0; x < monitors.length; x++ ) {
|
||||||
var monitor = monitors[x];
|
var monitor = monitors[x];
|
||||||
|
|
||||||
|
// Scale the frame
|
||||||
|
monitor_frame = $j('#monitorFrame'+monitor.id);
|
||||||
|
if ( ! monitor_frame ) {
|
||||||
|
console.log("Error finding frame for " + monitor.id );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( width )
|
||||||
|
monitor_frame.css('width',width+'px');
|
||||||
|
if ( height )
|
||||||
|
monitor_frame.css('height',height+'px');
|
||||||
/*Stream could be an applet so can't use moo tools*/
|
/*Stream could be an applet so can't use moo tools*/
|
||||||
var streamImg = $( 'liveStream'+monitor.id );
|
var streamImg = $( 'liveStream'+monitor.id );
|
||||||
if ( streamImg ) {
|
if ( streamImg ) {
|
||||||
|
@ -223,6 +268,42 @@ function initPage() {
|
||||||
monitors[i].start( delay );
|
monitors[i].start( delay );
|
||||||
}
|
}
|
||||||
selectLayout($('layout'));
|
selectLayout($('layout'));
|
||||||
|
|
||||||
|
$j('#monitors .monitorFrame').draggable({
|
||||||
|
cursor: 'crosshair',
|
||||||
|
revert: 'invalid'
|
||||||
|
});
|
||||||
|
|
||||||
|
function toGrid(value) {
|
||||||
|
return Math.round(value / 80) * 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
$j('#monitors').droppable({
|
||||||
|
accept: '#monitors .monitorFrame',
|
||||||
|
drop: function(event, ui) {
|
||||||
|
//console.log(event);
|
||||||
|
$j(this).removeClass('border over');
|
||||||
|
$j(ui.draggable).detach().
|
||||||
|
appendTo($j(this).find('ul')).
|
||||||
|
draggable({
|
||||||
|
containment: '.fw-content',
|
||||||
|
cursor: 'help',
|
||||||
|
grid: [ 80, 80 ]
|
||||||
|
}).
|
||||||
|
css({
|
||||||
|
position: 'absolute',
|
||||||
|
left: toGrid(event.clientX - $j('#monitors').offset().left),
|
||||||
|
top: toGrid(event.clientY - $j('#monitors').offset().top)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
over: function(event, elem) {
|
||||||
|
console.log('over');
|
||||||
|
$j(this).addClass('over');
|
||||||
|
},
|
||||||
|
out: function(event, elem) {
|
||||||
|
$j(this).removeClass('over');
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kick everything off
|
// Kick everything off
|
||||||
|
|
|
@ -38,5 +38,14 @@ monitorData[monitorData.length] = {
|
||||||
'server_url': '<?php echo $monitor->Server()->Url().(ZM_MIN_STREAMING_PORT?':'.(ZM_MIN_STREAMING_PORT+$monitor->Id()):'').$_SERVER['PHP_SELF'] ?>'
|
'server_url': '<?php echo $monitor->Server()->Url().(ZM_MIN_STREAMING_PORT?':'.(ZM_MIN_STREAMING_PORT+$monitor->Id()):'').$_SERVER['PHP_SELF'] ?>'
|
||||||
};
|
};
|
||||||
<?php
|
<?php
|
||||||
}
|
} // end foreach monitor
|
||||||
|
?>
|
||||||
|
layouts = new Array();
|
||||||
|
layouts[0] = {}; // reserved, should hold which fields to clear when transitioning
|
||||||
|
<?php
|
||||||
|
foreach ( $layouts as $layout ) {
|
||||||
|
?>
|
||||||
|
layouts[<?php echo $layout->Id() ?>] = <?php echo $layout->Positions() ?>;
|
||||||
|
<?php
|
||||||
|
} // end foreach layout
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -84,7 +84,11 @@ function imagedone( obj, monId, success ) {
|
||||||
if ( ! success ) {
|
if ( ! success ) {
|
||||||
// if we had a failrue queue up the no-data image
|
// if we had a failrue queue up the no-data image
|
||||||
//loadImage2Monitor(monId,"no data"); // leave the staged URL if there is one, just ignore it here.
|
//loadImage2Monitor(monId,"no data"); // leave the staged URL if there is one, just ignore it here.
|
||||||
loadNoData( monId );
|
if ( liveMode ) {
|
||||||
|
writeText( monId, "Camera Offline" );
|
||||||
|
} else {
|
||||||
|
writeText( monId, "No Data" );
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if ( monitorLoadingStageURL[monId] == "" ) {
|
if ( monitorLoadingStageURL[monId] == "" ) {
|
||||||
console.log("Not showing image for " + monId );
|
console.log("Not showing image for " + monId );
|
||||||
|
@ -114,6 +118,21 @@ function loadNoData( monId ) {
|
||||||
console.log("No monId in loadNoData");
|
console.log("No monId in loadNoData");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function writeText( monId, text ) {
|
||||||
|
if ( monId ) {
|
||||||
|
var canvasCtx = monitorCanvasCtx[monId];
|
||||||
|
var canvasObj = monitorCanvasObj[monId];
|
||||||
|
//canvasCtx.fillStyle="white";
|
||||||
|
//canvasCtx.fillRect(0, 0, canvasObj.width, canvasObj.height);
|
||||||
|
var textSize=canvasObj.width * 0.15;
|
||||||
|
canvasCtx.font = "600 " + textSize.toString() + "px Arial";
|
||||||
|
canvasCtx.fillStyle="white";
|
||||||
|
var textWidth = canvasCtx.measureText(text).width;
|
||||||
|
canvasCtx.fillText(text,canvasObj.width/2 - textWidth/2,canvasObj.height/2);
|
||||||
|
} else {
|
||||||
|
console.log("No monId in loadNoData");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Either draws the
|
// Either draws the
|
||||||
function loadImage2Monitor( monId, url ) {
|
function loadImage2Monitor( monId, url ) {
|
||||||
|
@ -123,14 +142,16 @@ function loadImage2Monitor( monId, url ) {
|
||||||
} else {
|
} else {
|
||||||
if ( monitorImageObject[monId].src == url ) return; // do nothing if it's the same
|
if ( monitorImageObject[monId].src == url ) return; // do nothing if it's the same
|
||||||
if ( url == 'no data' ) {
|
if ( url == 'no data' ) {
|
||||||
loadNoData( monId );
|
writeText(monId, 'No Data');
|
||||||
} else {
|
} else {
|
||||||
|
//writeText(monId, 'Loading...');
|
||||||
monitorLoading[monId] = true;
|
monitorLoading[monId] = true;
|
||||||
monitorLoadStartTimems[monId] = new Date().getTime();
|
monitorLoadStartTimems[monId] = new Date().getTime();
|
||||||
monitorImageObject[monId].src = url; // starts a load but doesn't refresh yet, wait until ready
|
monitorImageObject[monId].src = url; // starts a load but doesn't refresh yet, wait until ready
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function timerFire() {
|
function timerFire() {
|
||||||
// See if we need to reschedule
|
// See if we need to reschedule
|
||||||
if ( currentDisplayInterval != timerInterval || currentSpeed == 0 ) {
|
if ( currentDisplayInterval != timerInterval || currentSpeed == 0 ) {
|
||||||
|
@ -665,15 +686,17 @@ function showOneMonitor(monId) {
|
||||||
// link out to the normal view of one event's data
|
// link out to the normal view of one event's data
|
||||||
// We know the monitor, need to determine the event based on current time
|
// We know the monitor, need to determine the event based on current time
|
||||||
var url;
|
var url;
|
||||||
if ( liveMode != 0 )
|
if ( liveMode != 0 ) {
|
||||||
url="?view=watch&mid=" + monId.toString();
|
url="?view=watch&mid=" + monId.toString();
|
||||||
else
|
createPopup(url, 'zmWatch', 'watch', monitorWidth[monId], monitorHeight[monId] );
|
||||||
|
} else {
|
||||||
for ( var i=0, len=eId.length; i<len; i++ ) {
|
for ( var i=0, len=eId.length; i<len; i++ ) {
|
||||||
if ( eMonId[i] == monId && currentTimeSecs >= eStartSecs[i] && currentTimeSecs <= eEndSecs[i] )
|
if ( eMonId[i] == monId && currentTimeSecs >= eStartSecs[i] && currentTimeSecs <= eEndSecs[i] )
|
||||||
url="?view=event&eid=" + eId[i] + '&fid=' + parseInt(Math.max(1, Math.min(eventFrames[i], eventFrames[i] * (currentTimeSecs - eStartSecs[i]) / (eEndSecs[i] - eStartSecs[i] + 1) ) ));
|
url="?view=event&eid=" + eId[i] + '&fid=' + parseInt(Math.max(1, Math.min(eventFrames[i], eventFrames[i] * (currentTimeSecs - eStartSecs[i]) / (eEndSecs[i] - eStartSecs[i] + 1) ) ));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
createPopup(url, 'zmEvent', 'event', monitorWidth[eMonId[i]], monitorHeight[eMonId[i]]);
|
createPopup(url, 'zmEvent', 'event', monitorWidth[monId], monitorHeight[monId]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function zoom(monId,scale) {
|
function zoom(monId,scale) {
|
||||||
|
|
|
@ -122,7 +122,7 @@ if ( ! $monitor ) {
|
||||||
'FrameSkip' => 0,
|
'FrameSkip' => 0,
|
||||||
'MotionFrameSkip' => 0,
|
'MotionFrameSkip' => 0,
|
||||||
'EventPrefix' => 'Event-',
|
'EventPrefix' => 'Event-',
|
||||||
'AnalysisFPS' => '',
|
'AnalysisFPSLimit' => '',
|
||||||
'AnalysisUpdateDelay' => 0,
|
'AnalysisUpdateDelay' => 0,
|
||||||
'MaxFPS' => '',
|
'MaxFPS' => '',
|
||||||
'AlarmMaxFPS' => '',
|
'AlarmMaxFPS' => '',
|
||||||
|
@ -170,8 +170,8 @@ if ( isset( $_REQUEST['newMonitor'] ) ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
# What if it has less zeros? This is not robust code.
|
# What if it has less zeros? This is not robust code.
|
||||||
if ( $monitor->AnalysisFPS() == '0.00' )
|
if ( $monitor->AnalysisFPSLimit() == '0.00' )
|
||||||
$monitor->AnalysisFPS( '' );
|
$monitor->AnalysisFPSLimit( '' );
|
||||||
if ( $monitor->MaxFPS() == '0.00' )
|
if ( $monitor->MaxFPS() == '0.00' )
|
||||||
$monitor->MaxFPS( '' );
|
$monitor->MaxFPS( '' );
|
||||||
if ( $monitor->AlarmMaxFPS() == '0.00' )
|
if ( $monitor->AlarmMaxFPS() == '0.00' )
|
||||||
|
@ -538,7 +538,7 @@ if ( $tab != 'general' ) {
|
||||||
<input type="hidden" name="newMonitor[Enabled]" value="<?php echo validHtmlStr($monitor->Enabled()) ?>"/>
|
<input type="hidden" name="newMonitor[Enabled]" value="<?php echo validHtmlStr($monitor->Enabled()) ?>"/>
|
||||||
<input type="hidden" name="newMonitor[RefBlendPerc]" value="<?php echo validHtmlStr($monitor->RefBlendPerc()) ?>"/>
|
<input type="hidden" name="newMonitor[RefBlendPerc]" value="<?php echo validHtmlStr($monitor->RefBlendPerc()) ?>"/>
|
||||||
<input type="hidden" name="newMonitor[AlarmRefBlendPerc]" value="<?php echo validHtmlStr($monitor->AlarmRefBlendPerc()) ?>"/>
|
<input type="hidden" name="newMonitor[AlarmRefBlendPerc]" value="<?php echo validHtmlStr($monitor->AlarmRefBlendPerc()) ?>"/>
|
||||||
<input type="hidden" name="newMonitor[AnalysisFPS]" value="<?php echo validHtmlStr($monitor->AnalysisFPS()) ?>"/>
|
<input type="hidden" name="newMonitor[AnalysisFPSLimit]" value="<?php echo validHtmlStr($monitor->AnalysisFPSLimit()) ?>"/>
|
||||||
<input type="hidden" name="newMonitor[MaxFPS]" value="<?php echo validHtmlStr($monitor->MaxFPS()) ?>"/>
|
<input type="hidden" name="newMonitor[MaxFPS]" value="<?php echo validHtmlStr($monitor->MaxFPS()) ?>"/>
|
||||||
<input type="hidden" name="newMonitor[AlarmMaxFPS]" value="<?php echo validHtmlStr($monitor->AlarmMaxFPS()) ?>"/>
|
<input type="hidden" name="newMonitor[AlarmMaxFPS]" value="<?php echo validHtmlStr($monitor->AlarmMaxFPS()) ?>"/>
|
||||||
<?php
|
<?php
|
||||||
|
@ -665,7 +665,7 @@ if ( ZM_HAS_V4L && ($tab != 'misc' || $monitor->Type()!= 'Local') ) {
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<table id="contentTable" class="major" cellspacing="0">
|
<table id="contentTable" class="major">
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
switch ( $tab ) {
|
switch ( $tab ) {
|
||||||
|
@ -727,7 +727,7 @@ switch ( $tab ) {
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr><td><?php echo translate('AnalysisFPS') ?></td><td><input type="text" name="newMonitor[AnalysisFPS]" value="<?php echo validHtmlStr($monitor->AnalysisFPS()) ?>" size="6"/></td></tr>
|
<tr><td><?php echo translate('AnalysisFPS') ?></td><td><input type="text" name="newMonitor[AnalysisFPSLimit]" value="<?php echo validHtmlStr($monitor->AnalysisFPSLimit()) ?>" size="6"/></td></tr>
|
||||||
<?php
|
<?php
|
||||||
if ( $monitor->Type() != 'Local' && $monitor->Type() != 'File' && $monitor->Type() != 'NVSocket' ) {
|
if ( $monitor->Type() != 'Local' && $monitor->Type() != 'File' && $monitor->Type() != 'NVSocket' ) {
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
<?php
|
||||||
|
//
|
||||||
|
// ZoneMinder web function view file, $Date$, $Revision$
|
||||||
|
// Copyright (C) 2001-2008 Philip Coombes
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$monitors = Monitor::find_all( array('Id' => $_REQUEST['mids'] ) );
|
||||||
|
$monitor = $monitors[0];
|
||||||
|
$servers = Server::find_all();
|
||||||
|
$ServersById = array();
|
||||||
|
foreach ( $servers as $S ) {
|
||||||
|
$ServersById[$S->Id()] = $S;
|
||||||
|
}
|
||||||
|
$storage_areas = Storage::find_all();
|
||||||
|
$StorageById = array();
|
||||||
|
foreach ( $storage_areas as $S ) {
|
||||||
|
$StorageById[$S->Id()] = $S;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$focusWindow = true;
|
||||||
|
|
||||||
|
xhtmlHeaders(__FILE__, translate('Function'));
|
||||||
|
?>
|
||||||
|
<body>
|
||||||
|
<div id="page">
|
||||||
|
<div id="header">
|
||||||
|
<h2><?php echo translate('Function') ?></h2>
|
||||||
|
</div>
|
||||||
|
<div id="content">
|
||||||
|
The following monitors will have these settings update when you click Save:<br/><br/>
|
||||||
|
<?php echo implode('<br/>', array_map( function($m){return $m->Id().' ' .$m->Name();}, $monitors ) ); ?>
|
||||||
|
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||||
|
<input type="hidden" name="view" value="none"/>
|
||||||
|
<input type="hidden" name="action" value="save"/>
|
||||||
|
<input type="hidden" name="object" value="Monitor"/>
|
||||||
|
<?php
|
||||||
|
echo implode(
|
||||||
|
"\n",
|
||||||
|
array_map( function($m){
|
||||||
|
return '<input type="hidden" name="mids[]" value="'.$m->Id().'"/>';
|
||||||
|
}, $monitors )
|
||||||
|
);
|
||||||
|
if ( count($ServersById) > 0 ) { ?>
|
||||||
|
<p class="Server"><label><?php echo translate('Server')?></label>
|
||||||
|
<?php echo htmlSelect( 'newMonitor[ServerId]', array(''=>'None')+$ServersById, $monitor->ServerId() ); ?>
|
||||||
|
</p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
if ( count($StorageById) > 0 ) {
|
||||||
|
?>
|
||||||
|
<p class="Storage"><label><?php echo translate('Storage')?></label>
|
||||||
|
<?php echo htmlSelect( 'newMonitor[StorageId]', array(''=>'All')+$StorageById, $monitor->StorageId() ); ?>
|
||||||
|
</p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<p><label><?php echo translate('Function') ?></label>
|
||||||
|
<?php
|
||||||
|
$options = array();
|
||||||
|
foreach ( getEnumValues('Monitors', 'Function') as $opt ) {
|
||||||
|
$options[$opt] = translate('Fn'.$opt);
|
||||||
|
}
|
||||||
|
echo htmlSelect( 'newMonitor[Function]', $options, $monitor->Function() );
|
||||||
|
?>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="newMonitor[Enabled]"><?php echo translate('Enabled') ?></label>
|
||||||
|
<input type="checkbox" name="newMonitor[Enabled]" id="newMonitor[Enabled]" value="1"<?php if ( !empty($monitors[0]->Enabled()) ) { ?> checked="checked"<?php } ?>/>
|
||||||
|
</p>
|
||||||
|
<div id="contentButtons">
|
||||||
|
<input type="submit" value="<?php echo translate('Save') ?>"/>
|
||||||
|
<input type="button" value="<?php echo translate('Cancel') ?>" onclick="closeWindow()"/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -23,6 +23,8 @@ if ( !canView('Stream') ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require_once('includes/MontageLayout.php');
|
||||||
|
|
||||||
$showControl = false;
|
$showControl = false;
|
||||||
$showZones = false;
|
$showZones = false;
|
||||||
if ( isset( $_REQUEST['showZones'] ) ) {
|
if ( isset( $_REQUEST['showZones'] ) ) {
|
||||||
|
@ -59,6 +61,7 @@ if ( ! $scale )
|
||||||
|
|
||||||
$focusWindow = true;
|
$focusWindow = true;
|
||||||
|
|
||||||
|
/*
|
||||||
$layouts = array(
|
$layouts = array(
|
||||||
'montage_freeform.css' => translate('MtgDefault'),
|
'montage_freeform.css' => translate('MtgDefault'),
|
||||||
'montage_2wide.css' => translate('Mtg2widgrd'),
|
'montage_2wide.css' => translate('Mtg2widgrd'),
|
||||||
|
@ -66,6 +69,15 @@ $layouts = array(
|
||||||
'montage_4wide.css' => translate('Mtg4widgrd'),
|
'montage_4wide.css' => translate('Mtg4widgrd'),
|
||||||
'montage_3wide50enlarge.css' => translate('Mtg3widgrx'),
|
'montage_3wide50enlarge.css' => translate('Mtg3widgrx'),
|
||||||
);
|
);
|
||||||
|
foreach ( MontageLayout::find() as $Layout ) {
|
||||||
|
$layouts[$Layout->Id()] = $Layout->Name();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
$layouts = MontageLayout::find(NULL, array('order'=>"lower('Name')"));
|
||||||
|
$layoutsById = array();
|
||||||
|
foreach ( $layouts as $l ) {
|
||||||
|
$layoutsById[$l->Id()] = $l->Name();
|
||||||
|
}
|
||||||
|
|
||||||
$layout = '';
|
$layout = '';
|
||||||
if ( isset($_COOKIE['zmMontageLayout']) )
|
if ( isset($_COOKIE['zmMontageLayout']) )
|
||||||
|
@ -91,6 +103,35 @@ ob_end_clean();
|
||||||
|
|
||||||
$groupSql = Group::get_group_sql( $group_id );
|
$groupSql = Group::get_group_sql( $group_id );
|
||||||
|
|
||||||
|
$servers = Server::find_all();
|
||||||
|
$ServersById = array();
|
||||||
|
foreach ( $servers as $S ) {
|
||||||
|
$ServersById[$S->Id()] = $S;
|
||||||
|
}
|
||||||
|
session_start();
|
||||||
|
foreach ( array('ServerFilter','StorageFilter') as $var ) {
|
||||||
|
if ( isset( $_REQUEST[$var] ) ) {
|
||||||
|
if ( $_REQUEST[$var] != '' ) {
|
||||||
|
$_SESSION[$var] = $_REQUEST[$var];
|
||||||
|
} else {
|
||||||
|
unset( $_SESSION[$var] );
|
||||||
|
}
|
||||||
|
} else if ( isset( $_COOKIE[$var] ) ) {
|
||||||
|
if ( $_COOKIE[$var] != '' ) {
|
||||||
|
$_SESSION[$var] = $_COOKIE[$var];
|
||||||
|
} else {
|
||||||
|
unset($_SESSION[$var]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
session_write_close();
|
||||||
|
|
||||||
|
$storage_areas = Storage::find_all();
|
||||||
|
$StorageById = array();
|
||||||
|
foreach ( $storage_areas as $S ) {
|
||||||
|
$StorageById[$S->Id()] = $S;
|
||||||
|
}
|
||||||
|
|
||||||
$monitor_id = 0;
|
$monitor_id = 0;
|
||||||
if ( isset( $_REQUEST['monitor_id'] ) ) {
|
if ( isset( $_REQUEST['monitor_id'] ) ) {
|
||||||
$monitor_id = $_REQUEST['monitor_id'];
|
$monitor_id = $_REQUEST['monitor_id'];
|
||||||
|
@ -100,15 +141,46 @@ if ( isset( $_REQUEST['monitor_id'] ) ) {
|
||||||
|
|
||||||
$monitors = array();
|
$monitors = array();
|
||||||
$monitors_dropdown = array( '' => 'All' );
|
$monitors_dropdown = array( '' => 'All' );
|
||||||
$sql = "SELECT * FROM Monitors WHERE Function != 'None'";
|
$conditions = array();
|
||||||
if ( $groupSql ) { $sql .= ' AND ' . $groupSql; };
|
$values = array();
|
||||||
if ( $monitor_id ) { $sql .= ' AND Id='.$monitor_id; };
|
|
||||||
|
|
||||||
$sql .= ' ORDER BY Sequence';
|
if ( $groupSql )
|
||||||
foreach( dbFetchAll( $sql ) as $row ) {
|
$conditions[] = $groupSql;
|
||||||
|
if ( isset($_SESSION['ServerFilter']) ) {
|
||||||
|
$conditions[] = 'ServerId=?';
|
||||||
|
$values[] = $_SESSION['ServerFilter'];
|
||||||
|
}
|
||||||
|
if ( isset($_SESSION['StorageFilter']) ) {
|
||||||
|
$conditions[] = 'StorageId=?';
|
||||||
|
$values[] = $_SESSION['StorageFilter'];
|
||||||
|
}
|
||||||
|
$sql = 'SELECT * FROM Monitors' . ( count($conditions) ? ' WHERE ' . implode(' AND ', $conditions ) : '' ).' ORDER BY Sequence ASC';
|
||||||
|
$monitor_rows = dbFetchAll( $sql, null, $values );
|
||||||
|
|
||||||
|
if ( $monitor_id ) {
|
||||||
|
$found_selected_monitor = false;
|
||||||
|
|
||||||
|
for ( $i = 0; $i < count($monitor_rows); $i++ ) {
|
||||||
|
if ( !visibleMonitor( $monitor_rows[$i]['Id'] ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$monitors_dropdown[$monitor_rows[$i]['Id']] = $monitor_rows[$i]['Name'];
|
||||||
|
if ( $monitor_rows[$i]['Id'] == $monitor_id ) {
|
||||||
|
$found_selected_monitor = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( ! $found_selected_monitor ) {
|
||||||
|
$monitor_id = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$monitors = array();
|
||||||
|
foreach( $monitor_rows as $row ) {
|
||||||
if ( !visibleMonitor( $row['Id'] ) ) {
|
if ( !visibleMonitor( $row['Id'] ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if ( $monitor_id and $row['Id'] != $monitor_id )
|
||||||
|
continue;
|
||||||
|
|
||||||
$row['Scale'] = $scale;
|
$row['Scale'] = $scale;
|
||||||
$row['PopupScale'] = reScale( SCALE_BASE, $row['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
|
$row['PopupScale'] = reScale( SCALE_BASE, $row['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
|
||||||
|
@ -141,11 +213,11 @@ if ( $showControl ) {
|
||||||
}
|
}
|
||||||
if ( $showZones ) {
|
if ( $showZones ) {
|
||||||
?>
|
?>
|
||||||
<a href="<?php echo $_SERVER['PHP_SELF'].'?view=montage&showZones=0'; ?>">Hide Zones</a>
|
<a id="ShowZones" href="<?php echo $_SERVER['PHP_SELF'].'?view=montage&showZones=0'; ?>">Hide Zones</a>
|
||||||
<?php
|
<?php
|
||||||
} else {
|
} else {
|
||||||
?>
|
?>
|
||||||
<a href="<?php echo $_SERVER['PHP_SELF'].'?view=montage&showZones=1'; ?>">Show Zones</a>
|
<a id="ShowZones" href="<?php echo $_SERVER['PHP_SELF'].'?view=montage&showZones=1'; ?>">Show Zones</a>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
@ -157,10 +229,31 @@ if ( $showZones ) {
|
||||||
<span id="monitorControl"><label><?php echo translate('Monitor') ?>:</label>
|
<span id="monitorControl"><label><?php echo translate('Monitor') ?>:</label>
|
||||||
<?php echo htmlSelect( 'monitor_id', $monitors_dropdown, $monitor_id, array('onchange'=>'changeMonitor(this);') ); ?>
|
<?php echo htmlSelect( 'monitor_id', $monitors_dropdown, $monitor_id, array('onchange'=>'changeMonitor(this);') ); ?>
|
||||||
</span>
|
</span>
|
||||||
|
<?php if ( count($ServersById) > 0 ) { ?>
|
||||||
|
<span class="ServerFilter"><label><?php echo translate('Server')?>:</label>
|
||||||
|
<?php
|
||||||
|
echo htmlSelect( 'ServerFilter', array(''=>'All')+$ServersById, (isset($_SESSION['ServerFilter'])?$_SESSION['ServerFilter']:''), array('onchange'=>'changeFilter(this);') );
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
if ( count($StorageById) > 0 ) { ?>
|
||||||
|
<span class="StorageFilter"><label><?php echo translate('Storage')?>:</label>
|
||||||
|
<?php
|
||||||
|
echo htmlSelect( 'StorageFilter', array(''=>'All')+$StorageById, (isset($_SESSION['StorageFilter'])?$_SESSION['StorageFilter']:''), array('onchange'=>'changeFilter(this);') );
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<br/>
|
||||||
<span id="widthControl"><label><?php echo translate('Width') ?>:</label><?php echo htmlSelect( 'width', $widths, $options['width'], 'changeSize(this);' ); ?></span>
|
<span id="widthControl"><label><?php echo translate('Width') ?>:</label><?php echo htmlSelect( 'width', $widths, $options['width'], 'changeSize(this);' ); ?></span>
|
||||||
<span id="heightControl"><label><?php echo translate('Height') ?>:</label><?php echo htmlSelect( 'height', $heights, $options['height'], 'changeSize(this);' ); ?></span>
|
<span id="heightControl"><label><?php echo translate('Height') ?>:</label><?php echo htmlSelect( 'height', $heights, $options['height'], 'changeSize(this);' ); ?></span>
|
||||||
<span id="scaleControl"><label><?php echo translate('Scale') ?>:</label><?php echo htmlSelect( 'scale', $scales, $scale, 'changeScale(this);' ); ?></span>
|
<span id="scaleControl"><label><?php echo translate('Scale') ?>:</label><?php echo htmlSelect( 'scale', $scales, $scale, 'changeScale(this);' ); ?></span>
|
||||||
<span id="layoutControl"><label for="layout"><?php echo translate('Layout') ?>:</label><?php echo htmlSelect( 'layout', $layouts, $layout, 'selectLayout(this);' )?></span>
|
<span id="layoutControl">
|
||||||
|
<label for="layout"><?php echo translate('Layout') ?>:</label>
|
||||||
|
<?php echo htmlSelect( 'layout', $layoutsById, $layout, 'selectLayout(this);' )?>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
|
|
@ -62,10 +62,30 @@ ob_end_clean();
|
||||||
|
|
||||||
$groupSql = Group::get_group_sql( $group_id );
|
$groupSql = Group::get_group_sql( $group_id );
|
||||||
|
|
||||||
|
$servers = Server::find_all();
|
||||||
|
$ServersById = array();
|
||||||
|
foreach ( $servers as $S ) {
|
||||||
|
$ServersById[$S->Id()] = $S;
|
||||||
|
}
|
||||||
|
$storage_areas = Storage::find_all();
|
||||||
|
$StorageById = array();
|
||||||
|
foreach ( $storage_areas as $S ) {
|
||||||
|
$StorageById[$S->Id()] = $S;
|
||||||
|
}
|
||||||
session_start();
|
session_start();
|
||||||
foreach ( array('minTime','maxTime') as $var ) {
|
foreach ( array('minTime','maxTime','ServerFilter','StorageFilter') as $var ) {
|
||||||
if ( isset( $_REQUEST[$var] ) ) {
|
if ( isset( $_REQUEST[$var] ) ) {
|
||||||
|
if ( $_REQUEST[$var] != '' ) {
|
||||||
$_SESSION[$var] = $_REQUEST[$var];
|
$_SESSION[$var] = $_REQUEST[$var];
|
||||||
|
} else {
|
||||||
|
unset( $_SESSION[$var] );
|
||||||
|
}
|
||||||
|
} else if ( isset( $_COOKIE[$var] ) ) {
|
||||||
|
if ( $_COOKIE[$var] != '' ) {
|
||||||
|
$_SESSION[$var] = $_COOKIE[$var];
|
||||||
|
} else {
|
||||||
|
unset($_SESSION[$var]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
session_write_close();
|
session_write_close();
|
||||||
|
@ -77,7 +97,19 @@ if ( isset( $_REQUEST['monitor_id'] ) ) {
|
||||||
$monitor_id = $_COOKIE['zmMonitorId'];
|
$monitor_id = $_COOKIE['zmMonitorId'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$monitorsSql = "SELECT * FROM Monitors WHERE Function != 'None'" . ( $groupSql ? ' AND ' . $groupSql : '');
|
$conditions = array();
|
||||||
|
$values = array();
|
||||||
|
|
||||||
|
if ( $groupSql )
|
||||||
|
$conditions[] = $groupSql;
|
||||||
|
if ( isset($_SESSION['ServerFilter']) ) {
|
||||||
|
$conditions[] = 'ServerId=?';
|
||||||
|
$values[] = $_SESSION['ServerFilter'];
|
||||||
|
}
|
||||||
|
if ( isset($_SESSION['StorageFilter']) ) {
|
||||||
|
$conditions[] = 'StorageId=?';
|
||||||
|
$values[] = $_SESSION['StorageFilter'];
|
||||||
|
}
|
||||||
|
|
||||||
// Note that this finds incomplete events as well, and any frame records written, but still cannot "see" to the end frame
|
// Note that this finds incomplete events as well, and any frame records written, but still cannot "see" to the end frame
|
||||||
// if the bulk record has not been written - to be able to include more current frames reduce bulk frame sizes (event size can be large)
|
// if the bulk record has not been written - to be able to include more current frames reduce bulk frame sizes (event size can be large)
|
||||||
|
@ -111,10 +143,14 @@ $frameSql = '
|
||||||
if ( ! empty( $user['MonitorIds'] ) ) {
|
if ( ! empty( $user['MonitorIds'] ) ) {
|
||||||
$eventsSql .= ' AND M.Id IN ('.$user['MonitorIds'].')';
|
$eventsSql .= ' AND M.Id IN ('.$user['MonitorIds'].')';
|
||||||
$monitorsSql .= ' AND Id IN ('.$user['MonitorIds'].')';
|
$monitorsSql .= ' AND Id IN ('.$user['MonitorIds'].')';
|
||||||
|
$monitor_ids = explode(',',$user['MonitorIds']);
|
||||||
|
$conditions[] .= 'Id IN ('.array_map( function(){return '?';}, $monitor_ids ) . ')';
|
||||||
|
array_push( $values, $monitor_ids );
|
||||||
$frameSql .= ' AND E.MonitorId IN ('.$user['MonitorIds'].')';
|
$frameSql .= ' AND E.MonitorId IN ('.$user['MonitorIds'].')';
|
||||||
}
|
}
|
||||||
if ( $monitor_id ) {
|
if ( $monitor_id ) {
|
||||||
$monitorsSql .= ' AND Id='.$monitor_id;
|
$conditions[] = 'Id=?';
|
||||||
|
$values[] = $monitor_id;
|
||||||
$eventsSql .= ' AND M.Id='.$monitor_id;
|
$eventsSql .= ' AND M.Id='.$monitor_id;
|
||||||
$frameSql .= ' AND E.MonitorId='.$monitor_id;
|
$frameSql .= ' AND E.MonitorId='.$monitor_id;
|
||||||
}
|
}
|
||||||
|
@ -191,8 +227,8 @@ $frameSql .= ' GROUP BY E.Id, E.MonitorId, F.TimeStamp, F.Delta ORDER BY E.Monit
|
||||||
|
|
||||||
|
|
||||||
$monitors = array();
|
$monitors = array();
|
||||||
$monitorsSql .= ' ORDER BY Sequence ASC';
|
$monitorsSql = 'SELECT * FROM Monitors' . ( count($conditions) ? ' WHERE ' . implode(' AND ', $conditions ) : '' ).' ORDER BY Sequence ASC';
|
||||||
foreach( dbFetchAll( $monitorsSql ) as $row ) {
|
foreach( dbFetchAll( $monitorsSql, null, $values ) as $row ) {
|
||||||
$Monitor = new Monitor( $row );
|
$Monitor = new Monitor( $row );
|
||||||
$monitors[] = $Monitor;
|
$monitors[] = $Monitor;
|
||||||
}
|
}
|
||||||
|
@ -214,6 +250,25 @@ xhtmlHeaders(__FILE__, translate('MontageReview') );
|
||||||
<span id="monitorControl"><label><?php echo translate('Monitor') ?>:</label>
|
<span id="monitorControl"><label><?php echo translate('Monitor') ?>:</label>
|
||||||
<?php Group::get_monitors_dropdown( $groupSql ? array( 'groupSql'=>$groupSql) : null ); ?>
|
<?php Group::get_monitors_dropdown( $groupSql ? array( 'groupSql'=>$groupSql) : null ); ?>
|
||||||
</span>
|
</span>
|
||||||
|
<?php
|
||||||
|
if ( count($ServersById) > 0 ) { ?>
|
||||||
|
<span class="ServerFilter"><label><?php echo translate('Server')?>:</label>
|
||||||
|
<?php
|
||||||
|
echo htmlSelect( 'ServerFilter', array(''=>'All')+$ServersById, (isset($_SESSION['ServerFilter'])?$_SESSION['ServerFilter']:''), array('onchange'=>'changeFilter(this);') );
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
if ( count($StorageById) > 0 ) { ?>
|
||||||
|
<span class="StorageFilter"><label><?php echo translate('Storage')?>:</label>
|
||||||
|
<?php
|
||||||
|
echo htmlSelect( 'StorageFilter', array(''=>'All')+$StorageById, (isset($_SESSION['StorageFilter'])?$_SESSION['StorageFilter']:''), array('onchange'=>'changeFilter(this);') );
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
<div id="DateTimeDiv">
|
<div id="DateTimeDiv">
|
||||||
<input type="datetime-local" name="minTime" id="minTime" value="<?php echo preg_replace('/ /', 'T', $minTime ) ?>" onchange="changeDateTime(this);"> to
|
<input type="datetime-local" name="minTime" id="minTime" value="<?php echo preg_replace('/ /', 'T', $minTime ) ?>" onchange="changeDateTime(this);"> to
|
||||||
<input type="datetime-local" name="maxTime" id="maxTime" value="<?php echo preg_replace('/ /', 'T', $maxTime ) ?>" onchange="changeDateTime(this);">
|
<input type="datetime-local" name="maxTime" id="maxTime" value="<?php echo preg_replace('/ /', 'T', $maxTime ) ?>" onchange="changeDateTime(this);">
|
||||||
|
@ -252,7 +307,7 @@ xhtmlHeaders(__FILE__, translate('MontageReview') );
|
||||||
<?php
|
<?php
|
||||||
// Monitor images - these had to be loaded after the monitors used were determined (after loading events)
|
// Monitor images - these had to be loaded after the monitors used were determined (after loading events)
|
||||||
foreach ($monitors as $m) {
|
foreach ($monitors as $m) {
|
||||||
echo '<canvas width="' . $m->Width() * $defaultScale . '" height="' . $m->Height() * $defaultScale . '" id="Monitor' . $m->Id() . '" style="border:1px solid ' . $m->WebColour() . '" onclick="clickMonitor(event,' . $m->Id() . ')">No Canvas Support!!</canvas>';
|
echo '<canvas title="'.$m->Id().' ' .$m->Name().'" width="' . $m->Width() * $defaultScale . '" height="' . $m->Height() * $defaultScale . '" id="Monitor' . $m->Id() . '" style="border:1px solid ' . $m->WebColour() . '" onclick="clickMonitor(event,' . $m->Id() . ')">No Canvas Support!!</canvas>';
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -204,6 +204,10 @@ foreach( array_map( 'basename', glob('skins/'.$current_skin.'/css/*',GLOB_ONLYDI
|
||||||
<tr>
|
<tr>
|
||||||
<th class="colName"><?php echo translate('Name') ?></th>
|
<th class="colName"><?php echo translate('Name') ?></th>
|
||||||
<th class="colHostname"><?php echo translate('Hostname') ?></th>
|
<th class="colHostname"><?php echo translate('Hostname') ?></th>
|
||||||
|
<th class="colStatus"><?php echo translate('Status') ?></th>
|
||||||
|
<th class="colCpuLoad"><?php echo translate('CpuLoad') ?></th>
|
||||||
|
<th class="colMemory"><?php echo translate('Free').'/'.translate('Total') . ' ' . translate('Memory') ?></th>
|
||||||
|
<th class="colSwap"><?php echo translate('Free').'/'.translate('Total') . ' ' . translate('Swap') ?></th>
|
||||||
<th class="colMark"><?php echo translate('Mark') ?></th>
|
<th class="colMark"><?php echo translate('Mark') ?></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -212,6 +216,11 @@ foreach( array_map( 'basename', glob('skins/'.$current_skin.'/css/*',GLOB_ONLYDI
|
||||||
<tr>
|
<tr>
|
||||||
<td class="colName"><?php echo makePopupLink( '?view=server&id='.$row['Id'], 'zmServer', 'server', validHtmlStr($row['Name']), $canEdit ) ?></td>
|
<td class="colName"><?php echo makePopupLink( '?view=server&id='.$row['Id'], 'zmServer', 'server', validHtmlStr($row['Name']), $canEdit ) ?></td>
|
||||||
<td class="colHostname"><?php echo makePopupLink( '?view=server&id='.$row['Id'], 'zmServer', 'server', validHtmlStr($row['Hostname']), $canEdit ) ?></td>
|
<td class="colHostname"><?php echo makePopupLink( '?view=server&id='.$row['Id'], 'zmServer', 'server', validHtmlStr($row['Hostname']), $canEdit ) ?></td>
|
||||||
|
<td class="colStatus"><?php echo makePopupLink( '?view=server&id='.$row['Id'], 'zmServer', 'server', validHtmlStr($row['Status']), $canEdit ) ?></td>
|
||||||
|
<td class="colCpuLoad"><?php echo makePopupLink( '?view=server&id='.$row['Id'], 'zmServer', 'server',$row['CpuLoad'], $canEdit ) ?></td>
|
||||||
|
<td class="colMemory"><?php echo makePopupLink( '?view=server&id='.$row['Id'], 'zmServer', 'server', human_filesize($row['FreeMem']) . ' / ' . human_filesize($row['TotalMem']), $canEdit ) ?></td>
|
||||||
|
<td class="colSwap"><?php echo makePopupLink( '?view=server&id='.$row['Id'], 'zmServer', 'server', human_filesize($row['FreeSwap']) . ' / ' . human_filesize($row['TotalSwap']) , $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 ?>
|
||||||
|
|
|
@ -121,6 +121,8 @@ Logger::Debug("Got virtual frame from Bulk Frames previous delta: " . $previousB
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
Fatal("Can't create frame images from video for this event (".$Event->DefaultVideo() );
|
Fatal("Can't create frame images from video for this event (".$Event->DefaultVideo() );
|
||||||
}
|
}
|
||||||
|
$Event->DiskSpace( null );
|
||||||
|
$Event->save();
|
||||||
} else {
|
} else {
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
Fatal("Can't create frame images from video becuase there is no video file for this event (".$Event->DefaultVideo() );
|
Fatal("Can't create frame images from video becuase there is no video file for this event (".$Event->DefaultVideo() );
|
||||||
|
|
Loading…
Reference in New Issue