Merge branch 'master' of github.com:/ZoneMinder/zoneminder

This commit is contained in:
Isaac Connor 2020-11-04 18:10:55 -05:00
commit 289612a826
64 changed files with 665 additions and 476 deletions

View File

@ -152,13 +152,13 @@ BEGIN
SET SET
ArchivedEvents = GREATEST(COALESCE(ArchivedEvents,0)-1,0), ArchivedEvents = GREATEST(COALESCE(ArchivedEvents,0)-1,0),
ArchivedEventDiskSpace = GREATEST(COALESCE(ArchivedEventDiskSpace,0) - COALESCE(OLD.DiskSpace,0),0) ArchivedEventDiskSpace = GREATEST(COALESCE(ArchivedEventDiskSpace,0) - COALESCE(OLD.DiskSpace,0),0)
WHERE Id=OLD.MonitorId; WHERE Monitors.Id=OLD.MonitorId;
ELSE ELSE
IF ( OLD.DiskSpace != NEW.DiskSpace ) THEN IF ( OLD.DiskSpace != NEW.DiskSpace ) THEN
UPDATE Events_Archived SET DiskSpace=NEW.DiskSpace WHERE EventId=NEW.Id; UPDATE Events_Archived SET DiskSpace=NEW.DiskSpace WHERE EventId=NEW.Id;
UPDATE Monitors SET UPDATE Monitors SET
ArchivedEventDiskSpace = GREATEST(COALESCE(ArchivedEventDiskSpace,0) - COALESCE(OLD.DiskSpace,0) + COALESCE(NEW.DiskSpace,0),0) ArchivedEventDiskSpace = GREATEST(COALESCE(ArchivedEventDiskSpace,0) - COALESCE(OLD.DiskSpace,0) + COALESCE(NEW.DiskSpace,0),0)
WHERE Id=OLD.MonitorId; WHERE Monitors.Id=OLD.MonitorId;
END IF; END IF;
END IF; END IF;
ELSEIF ( NEW.Archived AND diff ) THEN ELSEIF ( NEW.Archived AND diff ) THEN
@ -185,10 +185,10 @@ CREATE TRIGGER event_insert_trigger AFTER INSERT ON Events
FOR EACH ROW FOR EACH ROW
BEGIN BEGIN
INSERT INTO Events_Hour (EventId,MonitorId,StartTime,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.StartTime,0); INSERT INTO Events_Hour (EventId,MonitorId,StartDateTime,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.StartDateTime,0);
INSERT INTO Events_Day (EventId,MonitorId,StartTime,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.StartTime,0); INSERT INTO Events_Day (EventId,MonitorId,StartDateTime,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.StartDateTime,0);
INSERT INTO Events_Week (EventId,MonitorId,StartTime,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.StartTime,0); INSERT INTO Events_Week (EventId,MonitorId,StartDateTime,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.StartDateTime,0);
INSERT INTO Events_Month (EventId,MonitorId,StartTime,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.StartTime,0); INSERT INTO Events_Month (EventId,MonitorId,StartDateTime,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.StartDateTime,0);
UPDATE Monitors SET UPDATE Monitors SET
HourEvents = COALESCE(HourEvents,0)+1, HourEvents = COALESCE(HourEvents,0)+1,
DayEvents = COALESCE(DayEvents,0)+1, DayEvents = COALESCE(DayEvents,0)+1,

View File

@ -189,8 +189,8 @@ CREATE TABLE `Events` (
`SecondaryStorageId` smallint(5) unsigned default 0, `SecondaryStorageId` smallint(5) unsigned default 0,
`Name` varchar(64) NOT NULL default '', `Name` varchar(64) NOT NULL default '',
`Cause` varchar(32) NOT NULL default '', `Cause` varchar(32) NOT NULL default '',
`StartTime` datetime default NULL, `StartDateTime` datetime default NULL,
`EndTime` datetime default NULL, `EndDateTime` datetime default NULL,
`Width` smallint(5) unsigned NOT NULL default '0', `Width` smallint(5) unsigned NOT NULL default '0',
`Height` smallint(5) unsigned NOT NULL default '0', `Height` smallint(5) unsigned NOT NULL default '0',
`Length` decimal(10,2) NOT NULL default '0.00', `Length` decimal(10,2) NOT NULL default '0.00',
@ -216,52 +216,52 @@ CREATE TABLE `Events` (
PRIMARY KEY (`Id`), PRIMARY KEY (`Id`),
KEY `Events_MonitorId_idx` (`MonitorId`), KEY `Events_MonitorId_idx` (`MonitorId`),
KEY `Events_StorageId_idx` (`StorageId`), KEY `Events_StorageId_idx` (`StorageId`),
KEY `Events_StartTime_idx` (`StartTime`), KEY `Events_StartDateTime_idx` (`StartDateTime`),
KEY `Events_EndTime_DiskSpace` (`EndTime`,`DiskSpace`) KEY `Events_EndDateTime_DiskSpace` (`EndDateTime`,`DiskSpace`)
) ENGINE=@ZM_MYSQL_ENGINE@; ) ENGINE=@ZM_MYSQL_ENGINE@;
DROP TABLE IF EXISTS `Events_Hour`; DROP TABLE IF EXISTS `Events_Hour`;
CREATE TABLE `Events_Hour` ( CREATE TABLE `Events_Hour` (
`EventId` BIGINT unsigned NOT NULL, `EventId` BIGINT unsigned NOT NULL,
`MonitorId` int(10) unsigned NOT NULL, `MonitorId` int(10) unsigned NOT NULL,
`StartTime` datetime default NULL, `StartDateTime` datetime default NULL,
`DiskSpace` bigint default NULL, `DiskSpace` bigint default NULL,
PRIMARY KEY (`EventId`), PRIMARY KEY (`EventId`),
KEY `Events_Hour_MonitorId_idx` (`MonitorId`), KEY `Events_Hour_MonitorId_idx` (`MonitorId`),
KEY `Events_Hour_StartTime_idx` (`StartTime`) KEY `Events_Hour_StartDateTime_idx` (`StartDateTime`)
) ENGINE=@ZM_MYSQL_ENGINE@; ) ENGINE=@ZM_MYSQL_ENGINE@;
DROP TABLE IF EXISTS `Events_Day`; DROP TABLE IF EXISTS `Events_Day`;
CREATE TABLE `Events_Day` ( CREATE TABLE `Events_Day` (
`EventId` BIGINT unsigned NOT NULL, `EventId` BIGINT unsigned NOT NULL,
`MonitorId` int(10) unsigned NOT NULL, `MonitorId` int(10) unsigned NOT NULL,
`StartTime` datetime default NULL, `StartDateTime` datetime default NULL,
`DiskSpace` bigint default NULL, `DiskSpace` bigint default NULL,
PRIMARY KEY (`EventId`), PRIMARY KEY (`EventId`),
KEY `Events_Day_MonitorId_idx` (`MonitorId`), KEY `Events_Day_MonitorId_idx` (`MonitorId`),
KEY `Events_Day_StartTime_idx` (`StartTime`) KEY `Events_Day_StartDateTime_idx` (`StartDateTime`)
) ENGINE=@ZM_MYSQL_ENGINE@; ) ENGINE=@ZM_MYSQL_ENGINE@;
DROP TABLE IF EXISTS `Events_Week`; DROP TABLE IF EXISTS `Events_Week`;
CREATE TABLE `Events_Week` ( CREATE TABLE `Events_Week` (
`EventId` BIGINT unsigned NOT NULL, `EventId` BIGINT unsigned NOT NULL,
`MonitorId` int(10) unsigned NOT NULL, `MonitorId` int(10) unsigned NOT NULL,
`StartTime` datetime default NULL, `StartDateTime` datetime default NULL,
`DiskSpace` bigint default NULL, `DiskSpace` bigint default NULL,
PRIMARY KEY (`EventId`), PRIMARY KEY (`EventId`),
KEY `Events_Week_MonitorId_idx` (`MonitorId`), KEY `Events_Week_MonitorId_idx` (`MonitorId`),
KEY `Events_Week_StartTime_idx` (`StartTime`) KEY `Events_Week_StartDateTime_idx` (`StartDateTime`)
) ENGINE=@ZM_MYSQL_ENGINE@; ) ENGINE=@ZM_MYSQL_ENGINE@;
DROP TABLE IF EXISTS `Events_Month`; DROP TABLE IF EXISTS `Events_Month`;
CREATE TABLE `Events_Month` ( CREATE TABLE `Events_Month` (
`EventId` BIGINT unsigned NOT NULL, `EventId` BIGINT unsigned NOT NULL,
`MonitorId` int(10) unsigned NOT NULL, `MonitorId` int(10) unsigned NOT NULL,
`StartTime` datetime default NULL, `StartDateTime` datetime default NULL,
`DiskSpace` bigint default NULL, `DiskSpace` bigint default NULL,
PRIMARY KEY (`EventId`), PRIMARY KEY (`EventId`),
KEY `Events_Month_MonitorId_idx` (`MonitorId`), KEY `Events_Month_MonitorId_idx` (`MonitorId`),
KEY `Events_Month_StartTime_idx` (`StartTime`) KEY `Events_Month_StartDateTime_idx` (`StartDateTime`)
) ENGINE=@ZM_MYSQL_ENGINE@; ) ENGINE=@ZM_MYSQL_ENGINE@;
@ -804,7 +804,7 @@ INSERT INTO `Filters`
VALUES VALUES
( (
'PurgeWhenFull', 'PurgeWhenFull',
'{"sort_field":"Id","terms":[{"val":0,"attr":"Archived","op":"="},{"cnj":"and","val":95,"attr":"DiskPercent","op":">="}],"limit":100,"sort_asc":1}', '{"sort_field":"Id","terms":[{"val":0,"attr":"Archived","op":"="},{"cnj":"and","val":95,"attr":"DiskPercent","op":">="},{"cnj":"and","obr":"0","attr":"EndDateTime","op":"IS NOT","val":"NULL","cbr":"0"}],"limit":100,"sort_asc":1}',
0/*AutoArchive*/, 0/*AutoArchive*/,
0/*AutoVideo*/, 0/*AutoVideo*/,
0/*AutoUpload*/, 0/*AutoUpload*/,
@ -848,7 +848,7 @@ INSERT INTO `Filters`
) )
VALUES ( VALUES (
'Update DiskSpace', 'Update DiskSpace',
'{"terms":[{"attr":"DiskSpace","op":"IS","val":"NULL"}]}', '{"terms":[{"attr":"DiskSpace","op":"IS","val":"NULL"},{"cnj":"and","obr":"0","attr":"EndDateTime","op":"IS NOT","val":"NULL","cbr":"0"}]}',
0/*AutoArchive*/, 0/*AutoArchive*/,
0/*AutoVideo*/, 0/*AutoVideo*/,
0/*AutoUpload*/, 0/*AutoUpload*/,

View File

@ -1,73 +1,91 @@
/* Change Id type to BIGINT. */ /* Change Id type to BIGINT. */
SELECT 'Updating Events.Id to BIGINT'; set @exist := (SELECT count(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'Events' AND COLUMN_NAME = 'Id' and DATA_TYPE='bigint');
ALTER TABLE Events MODIFY Id bigint unsigned NOT NULL auto_increment;
set @sqlstmt := if( @exist = 0, "ALTER TABLE Events MODIFY Id bigint unsigned NOT NULL auto_increment", "SELECT 'Events.Id is already BIGINT'");
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
/* Add FOREIGN KEYS After deleting lost records */ /* Add FOREIGN KEYS After deleting lost records */
SELECT 'Adding foreign key for EventId to Frames';
set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Frames' and column_name='EventId' and referenced_table_name='Events' and referenced_column_name='Id'); set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Frames' and column_name='EventId' and referenced_table_name='Events' and referenced_column_name='Id');
set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'"); set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'");
set @sqlstmt := if( @exist = 1, "SELECT 'FOREIGN KEY EventId in Frames already exists'", @sqlstmt);
set @sqlstmt := if( @exist = 0, "SELECT 'Adding foreign key for EventId to Frames'", @sqlstmt);
PREPARE stmt FROM @sqlstmt; PREPARE stmt FROM @sqlstmt;
EXECUTE stmt; EXECUTE stmt;
set @sqlstmt := if( @exist > 0, "SELECT 'FOREIGN KEY for EventId in Frames already exists'", "DELETE FROM Frames WHERE EventId NOT IN (SELECT Id FROM Events)"); set @sqlstmt := if( @exist = 0, "SELECT 'Deleting unlinked Frames'", "SELECT '.'");
PREPARE stmt FROM @sqlstmt; PREPARE stmt FROM @sqlstmt;
EXECUTE stmt; EXECUTE stmt;
set @sqlstmt := if( @exist = 0, "DELETE FROM Frames WHERE EventId NOT IN (SELECT Id FROM Events)", "SELECT '.'");
set @sqlstmt := if( @exist > 0, "SELECT 'Ok'", "ALTER TABLE Frames ADD FOREIGN KEY (EventId) REFERENCES Events (Id) ON DELETE CASCADE"); PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
set @sqlstmt := if( @exist = 0, "ALTER TABLE Frames ADD FOREIGN KEY (EventId) REFERENCES Events (Id) ON DELETE CASCADE", "SELECT '.'");
PREPARE stmt FROM @sqlstmt; PREPARE stmt FROM @sqlstmt;
EXECUTE stmt; EXECUTE stmt;
SELECT 'Adding foreign key for EventId to Stats';
set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Stats' and column_name='EventId' and referenced_table_name='Events' and referenced_column_name='Id'); set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Stats' and column_name='EventId' and referenced_table_name='Events' and referenced_column_name='Id');
set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'"); set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'");
set @sqlstmt := if( @exist = 1, "SELECT 'FOREIGN KEY EventId in Stats already exists'", @sqlstmt);
set @sqlstmt := if( @exist = 0, "SELECT 'Adding FOREIGN KEY for EventId to Stats'", @sqlstmt);
PREPARE stmt FROM @sqlstmt; PREPARE stmt FROM @sqlstmt;
EXECUTE stmt; EXECUTE stmt;
set @sqlstmt := if( @exist > 0, "SELECT 'FOREIGN KEY for EventId in Stats already exists'", "DELETE FROM Stats WHERE EventId NOT IN (SELECT Id FROM Events);"); set @sqlstmt := if( @exist = 0, "SELECT 'Deleting unlinked Stats'", "SELECT '.'");
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
set @sqlstmt := if( @exist = 0, "DELETE FROM Stats WHERE EventId NOT IN (SELECT Id FROM Events);", "SELECT '.'");
PREPARE stmt FROM @sqlstmt; PREPARE stmt FROM @sqlstmt;
EXECUTE stmt; EXECUTE stmt;
set @sqlstmt := if( @exist > 0, "SELECT 'Ok'", "ALTER TABLE Stats ADD FOREIGN KEY (EventId) REFERENCES Events (Id) ON DELETE CASCADE"); set @sqlstmt := if( @exist = 0, "ALTER TABLE Stats ADD FOREIGN KEY (EventId) REFERENCES Events (Id) ON DELETE CASCADE", "SELECT '.'");
PREPARE stmt FROM @sqlstmt; PREPARE stmt FROM @sqlstmt;
EXECUTE stmt; EXECUTE stmt;
SELECT 'Adding foreign key for MonitorId to Stats';
set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Stats' and column_name='MonitorId' and referenced_table_name='Monitors' and referenced_column_name='Id'); set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Stats' and column_name='MonitorId' and referenced_table_name='Monitors' and referenced_column_name='Id');
set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'"); set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'");
set @sqlstmt := if( @exist = 1, "SELECT 'FOREIGN KEY for MonitorId in Stats already exists'", @sql_stmt);
set @sqlstmt := if( @exist = 0, "SELECT 'Adding FOREIGN KEY for MonitorId to Stats'", @sqlstmt);
PREPARE stmt FROM @sqlstmt; PREPARE stmt FROM @sqlstmt;
EXECUTE stmt; EXECUTE stmt;
set @sqlstmt := if( @exist > 0, "SELECT 'FOREIGN KEY for MonitorId in Stats already exists'", "DELETE FROM Stats WHERE MonitorId NOT IN (SELECT Id FROM Monitors);"); set @sqlstmt := if( @exist = 0, "SELECT 'Deleting unlinked Stats'", "SELECT '.'");
PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
set @sqlstmt := if( @exist = 0, "DELETE FROM Stats WHERE MonitorId NOT IN (SELECT Id FROM Monitors);", "SELECT '.'");
PREPARE stmt FROM @sqlstmt; PREPARE stmt FROM @sqlstmt;
EXECUTE stmt; EXECUTE stmt;
set @sqlstmt := if( @exist > 0, "SELECT 'Ok'", "ALTER TABLE Stats ADD FOREIGN KEY (MonitorId) REFERENCES Monitors (Id) ON DELETE CASCADE"); set @sqlstmt := if( @exist = 0, "ALTER TABLE Stats ADD FOREIGN KEY (MonitorId) REFERENCES Monitors (Id) ON DELETE CASCADE", "SELECT '.'");
PREPARE stmt FROM @sqlstmt; PREPARE stmt FROM @sqlstmt;
EXECUTE stmt; EXECUTE stmt;
SELECT 'Adding foreign key for ZoneId to Stats';
set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Stats' and column_name='ZoneId' and referenced_table_name='Zones' and referenced_column_name='Id'); set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Stats' and column_name='ZoneId' and referenced_table_name='Zones' and referenced_column_name='Id');
set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'"); set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'");
set @sqlstmt := if( @exist = 1, "SELECT 'FOREIGN KEY for ZoneId in Stats already exists'", @sqlstmt);
set @sqlstmt := if( @exist = 0, "SELECT 'Adding foreign key for ZoneId to Stats'", @sqlstmt);
PREPARE stmt FROM @sqlstmt; PREPARE stmt FROM @sqlstmt;
EXECUTE stmt; EXECUTE stmt;
set @sqlstmt := if( @exist > 0, "SELECT 'FOREIGN KEY for ZoneId in Stats already exists'", "DELETE FROM Stats WHERE ZoneId NOT IN (SELECT Id FROM Zones);"); set @sqlstmt := if( @exist = 0, "SELECT 'Deleting unlinked Stats'", "SELECT 'Ok'");
PREPARE stmt FROM @sqlstmt; PREPARE stmt FROM @sqlstmt;
EXECUTE stmt; EXECUTE stmt;
set @sqlstmt := if( @exist = 0, "DELETE FROM Stats WHERE ZoneId NOT IN (SELECT Id FROM Zones);", "SELECT '.'");
set @sqlstmt := if( @exist > 0, "SELECT 'Ok'", "ALTER TABLE Stats ADD FOREIGN KEY (ZoneId) REFERENCES Zones (Id) ON DELETE CASCADE"); PREPARE stmt FROM @sqlstmt;
EXECUTE stmt;
set @sqlstmt := if( @exist = 0, "ALTER TABLE Stats ADD FOREIGN KEY (ZoneId) REFERENCES Zones (Id) ON DELETE CASCADE", "SELECT '.'");
PREPARE stmt FROM @sqlstmt; PREPARE stmt FROM @sqlstmt;
EXECUTE stmt; EXECUTE stmt;
SELECT 'Adding foreign key for MonitorId to Zones'; SELECT 'Adding foreign key for MonitorId to Zones';
set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Zones' and column_name='MonitorId' and referenced_table_name='Monitors' and referenced_column_name='Id'); set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Zones' and column_name='MonitorId' and referenced_table_name='Monitors' and referenced_column_name='Id');
set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'"); set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'");
PREPARE stmt FROM @sqlstmt; set @sqlstmt := if( @exist = 1, "SELECT 'FOREIGN KEY for MonitorId in Zones already exists'", @sqlstmnt);
EXECUTE stmt; set @sqlstmt := if( @exist = 0, "SELECT 'Adding foreign key for MonitorId in Zones'", @sqlstmnt);
set @sqlstmt := if( @exist > 0, "SELECT 'FOREIGN KEY for MonitorId in Zones already exists'", "SELECT 'FOREIGN KEY for MonitorId in Zones does not already exist'"); /*"SELECT 'FOREIGN KEY for MonitorId in Zones does not already exist'");*/
set @badzones := (select count(*) FROM Zones WHERE MonitorId NOT IN (SELECT Id FROM Monitors)); set @badzones := (select count(*) FROM Zones WHERE MonitorId NOT IN (SELECT Id FROM Monitors));
set @sqlstmt := if ( @badzones > 0, "SELECT 'You have Zones with no Monitor record in the Monitors table. Please delete them manually'", "ALTER TABLE Zones ADD FOREIGN KEY (MonitorId) REFERENCES Monitors (Id)"); set @sqlstmt := if ( @badzones > 0, "SELECT 'You have Zones with no Monitor record in the Monitors table. Please delete them manually'", "ALTER TABLE Zones ADD FOREIGN KEY (MonitorId) REFERENCES Monitors (Id)");
PREPARE stmt FROM @sqlstmt; PREPARE stmt FROM @sqlstmt;

101
db/zm_update-1.35.13.sql Normal file
View File

@ -0,0 +1,101 @@
/* DateTime is invalid and it being set here will cause warnings because it isn't in the dropdown set of values in Filter edit. */
UPDATE Config SET Value='StartDateTime' WHERE Name='ZM_WEB_EVENT_SORT_FIELD' AND Value='DateTime';
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Events'
AND column_name = 'StartDateTime'
) > 0,
"SELECT 'Column StartDateTime already exists in Events'",
"ALTER TABLE Events RENAME COLUMN StartTime TO StartDateTime"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Events'
AND column_name = 'EndDateTime'
) > 0,
"SELECT 'Column EndDateTime already exists in Events'",
"ALTER TABLE Events RENAME COLUMN EndTime TO EndDateTime"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Events_Hour'
AND column_name = 'StartDateTime'
) > 0,
"SELECT 'Column StartDateTime already exists in Events_Hour'",
"ALTER TABLE Events_Hour RENAME COLUMN StartTime TO StartDateTime"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Events_Day'
AND column_name = 'StartDateTime'
) > 0,
"SELECT 'Column StartDateTime already exists in Events_Day'",
"ALTER TABLE Events_Day RENAME COLUMN StartTime TO StartDateTime"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Events_Week'
AND column_name = 'StartDateTime'
) > 0,
"SELECT 'Column StartDateTime already exists in Events_Week'",
"ALTER TABLE Events_Week RENAME COLUMN StartTime TO StartDateTime"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Events_Month'
AND column_name = 'StartDateTime'
) > 0,
"SELECT 'Column StartDateTime already exists in Events_Month'",
"ALTER TABLE Events_Month RENAME COLUMN StartTime TO StartDateTime"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
delimiter //
DROP TRIGGER IF EXISTS event_insert_trigger//
/* The assumption is that when an Event is inserted, it has no size yet, so don't bother updating the DiskSpace, just the count.
* The DiskSpace will get update in the Event Update Trigger
*/
CREATE TRIGGER event_insert_trigger AFTER INSERT ON Events
FOR EACH ROW
BEGIN
INSERT INTO Events_Hour (EventId,MonitorId,StartDateTime,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.StartDateTime,0);
INSERT INTO Events_Day (EventId,MonitorId,StartDateTime,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.StartDateTime,0);
INSERT INTO Events_Week (EventId,MonitorId,StartDateTime,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.StartDateTime,0);
INSERT INTO Events_Month (EventId,MonitorId,StartDateTime,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.StartDateTime,0);
UPDATE Monitors SET
HourEvents = COALESCE(HourEvents,0)+1,
DayEvents = COALESCE(DayEvents,0)+1,
WeekEvents = COALESCE(WeekEvents,0)+1,
MonthEvents = COALESCE(MonthEvents,0)+1,
TotalEvents = COALESCE(TotalEvents,0)+1
WHERE Id=NEW.MonitorId;
END;
//
delimiter ;

View File

@ -28,7 +28,7 @@
%global _hardened_build 1 %global _hardened_build 1
Name: zoneminder Name: zoneminder
Version: 1.35.12 Version: 1.35.13
Release: 1%{?dist} Release: 1%{?dist}
Summary: A camera monitoring and analysis tool Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons Group: System Environment/Daemons

View File

@ -68,8 +68,8 @@ $serial = $primary_key = 'Id';
SecondaryStorageId SecondaryStorageId
Name Name
Cause Cause
StartTime StartDateTime
EndTime EndDateTime
Width Width
Height Height
Length Length
@ -111,8 +111,8 @@ sub Time {
$_[0]{Time} = $_[1]; $_[0]{Time} = $_[1];
} }
if ( ! defined $_[0]{Time} ) { if ( ! defined $_[0]{Time} ) {
if ( $_[0]{StartTime} ) { if ( $_[0]{StartDateTime} ) {
$_[0]{Time} = Date::Parse::str2time( $_[0]{StartTime} ); $_[0]{Time} = Date::Parse::str2time( $_[0]{StartDateTime} );
} }
} }
return $_[0]{Time}; return $_[0]{Time};
@ -349,6 +349,10 @@ sub GenerateVideo {
return; return;
} # end sub GenerateVideo } # end sub GenerateVideo
# Note about transactions, this function may be called with rows locked and hence in a transaction.
# So we will detect if we are in a transaction, and if not, start one. We will NOT do rollback or
# commits unless we started the transaction.
sub delete { sub delete {
my $event = $_[0]; my $event = $_[0];
@ -360,11 +364,11 @@ sub delete {
my $in_zmaudit = ( $0 =~ 'zmaudit.pl$'); my $in_zmaudit = ( $0 =~ 'zmaudit.pl$');
if ( ! $in_zmaudit ) { if ( ! $in_zmaudit ) {
if ( ! ( $event->{Id} and $event->{MonitorId} and $event->{StartTime} ) ) { if ( ! ( $event->{Id} and $event->{MonitorId} and $event->{StartDateTime} ) ) {
# zmfilter shouldn't delete anything in an odd situation. zmaudit will though. # zmfilter shouldn't delete anything in an odd situation. zmaudit will though.
my ( $caller, undef, $line ) = caller; my ( $caller, undef, $line ) = caller;
Warning("$0 Can't Delete event $event->{Id} from Monitor $event->{MonitorId} StartTime:". Warning("$0 Can't Delete event $event->{Id} from Monitor $event->{MonitorId} StartDateTime:".
(defined($event->{StartTime})?$event->{StartTime}:'undef')." from $caller:$line"); (defined($event->{StartDateTime})?$event->{StartDateTime}:'undef')." from $caller:$line");
return; return;
} }
if ( !($event->Storage()->Path() and -e $event->Storage()->Path()) ) { if ( !($event->Storage()->Path() and -e $event->Storage()->Path()) ) {
@ -375,26 +379,28 @@ sub delete {
if ( $$event{Id} ) { if ( $$event{Id} ) {
# Need to have an event Id if we are to delete from the db. # Need to have an event Id if we are to delete from the db.
Info("Deleting event $event->{Id} from Monitor $event->{MonitorId} StartTime:$event->{StartTime} from ".$event->Path()); Info("Deleting event $event->{Id} from Monitor $event->{MonitorId} StartDateTime:$event->{StartDateTime} from ".$event->Path());
$ZoneMinder::Database::dbh->ping(); $ZoneMinder::Database::dbh->ping();
$ZoneMinder::Database::dbh->begin_work(); my $in_transaction = $ZoneMinder::Database::dbh->{AutoCommit} ? 0 : 1;
#$event->lock_and_load();
ZoneMinder::Database::zmDbDo('DELETE FROM Frames WHERE EventId=?', $$event{Id}); $ZoneMinder::Database::dbh->begin_work() if ! $in_transaction;
if ( $ZoneMinder::Database::dbh->errstr() ) {
$ZoneMinder::Database::dbh->commit(); # Going to delete in order of least value to greatest value. Stats is least and references Frames
return;
}
ZoneMinder::Database::zmDbDo('DELETE FROM Stats WHERE EventId=?', $$event{Id}); ZoneMinder::Database::zmDbDo('DELETE FROM Stats WHERE EventId=?', $$event{Id});
if ( $ZoneMinder::Database::dbh->errstr() ) { if ( $ZoneMinder::Database::dbh->errstr() ) {
$ZoneMinder::Database::dbh->commit(); $ZoneMinder::Database::dbh->commit() if ! $in_transaction;
return;
}
ZoneMinder::Database::zmDbDo('DELETE FROM Frames WHERE EventId=?', $$event{Id});
if ( $ZoneMinder::Database::dbh->errstr() ) {
$ZoneMinder::Database::dbh->commit() if ! $in_transaction;
return; return;
} }
# Do it individually to avoid locking up the table for new events # Do it individually to avoid locking up the table for new events
ZoneMinder::Database::zmDbDo('DELETE FROM Events WHERE Id=?', $$event{Id}); ZoneMinder::Database::zmDbDo('DELETE FROM Events WHERE Id=?', $$event{Id});
$ZoneMinder::Database::dbh->commit(); $ZoneMinder::Database::dbh->commit() if ! $in_transaction;
} }
if ( ( $in_zmaudit or (!$Config{ZM_OPT_FAST_DELETE})) and $event->Storage()->DoDelete() ) { if ( ( $in_zmaudit or (!$Config{ZM_OPT_FAST_DELETE})) and $event->Storage()->DoDelete() ) {
@ -814,9 +820,9 @@ sub recover_timestamps {
my $duration = $last_timestamp - $first_timestamp; my $duration = $last_timestamp - $first_timestamp;
$Event->Length($duration); $Event->Length($duration);
$Event->StartTime( Date::Format::time2str('%Y-%m-%d %H:%M:%S', $first_timestamp) ); $Event->StartDateTime( Date::Format::time2str('%Y-%m-%d %H:%M:%S', $first_timestamp) );
$Event->EndTime( Date::Format::time2str('%Y-%m-%d %H:%M:%S', $last_timestamp) ); $Event->EndDateTime( Date::Format::time2str('%Y-%m-%d %H:%M:%S', $last_timestamp) );
Debug("From capture Jpegs have duration $duration = $last_timestamp - $first_timestamp : $$Event{StartTime} to $$Event{EndTime}"); Debug("From capture Jpegs have duration $duration = $last_timestamp - $first_timestamp : $$Event{StartDateTime} to $$Event{EndDateTime}");
$ZoneMinder::Database::dbh->begin_work(); $ZoneMinder::Database::dbh->begin_work();
foreach my $jpg ( @capture_jpgs ) { foreach my $jpg ( @capture_jpgs ) {
my ( $id ) = $jpg =~ /^(\d+)\-capture\.jpg$/; my ( $id ) = $jpg =~ /^(\d+)\-capture\.jpg$/;
@ -852,8 +858,8 @@ sub recover_timestamps {
} }
my $seconds = ($h*60*60)+($m*60)+$s; my $seconds = ($h*60*60)+($m*60)+$s;
$Event->Length($seconds.'.'.$u); $Event->Length($seconds.'.'.$u);
$Event->StartTime( Date::Format::time2str('%Y-%m-%d %H:%M:%S', $first_timestamp) ); $Event->StartDateTime( Date::Format::time2str('%Y-%m-%d %H:%M:%S', $first_timestamp) );
$Event->EndTime( Date::Format::time2str('%Y-%m-%d %H:%M:%S', $first_timestamp+$seconds) ); $Event->EndDateTime( Date::Format::time2str('%Y-%m-%d %H:%M:%S', $first_timestamp+$seconds) );
} }
if ( @mp4_files ) { if ( @mp4_files ) {
$Event->DefaultVideo($mp4_files[0]); $Event->DefaultVideo($mp4_files[0]);

View File

@ -149,7 +149,7 @@ sub Sql {
my $filter_expr = ZoneMinder::General::jsonDecode($self->{Query_json}); my $filter_expr = ZoneMinder::General::jsonDecode($self->{Query_json});
my $sql = 'SELECT E.*, my $sql = 'SELECT E.*,
unix_timestamp(E.StartTime) as Time, unix_timestamp(E.StartDateTime) as Time,
M.Name as MonitorName, M.Name as MonitorName,
M.DefaultRate, M.DefaultRate,
M.DefaultScale M.DefaultScale
@ -184,27 +184,25 @@ sub Sql {
$self->{Sql} .= $Config{ZM_SERVER_ID}; $self->{Sql} .= $Config{ZM_SERVER_ID};
# StartTime options # StartTime options
} elsif ( $term->{attr} eq 'DateTime' ) { } elsif ( $term->{attr} eq 'DateTime' ) {
$self->{Sql} .= 'E.StartTime'; $self->{Sql} .= 'E.StartDateTime';
} 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.StartDateTime )';
} elsif ( $term->{attr} eq 'StartDate' ) { } elsif ( $term->{attr} eq 'StartDate' ) {
$self->{Sql} .= 'to_days( E.StartTime )'; $self->{Sql} .= 'to_days( E.StartDateTime )';
} elsif ( $term->{attr} eq 'Time' or $term->{attr} eq 'StartTime' ) { } elsif ( $term->{attr} eq 'Time' or $term->{attr} eq 'StartTime' ) {
$self->{Sql} .= 'extract( hour_second from E.StartTime )'; $self->{Sql} .= 'extract( hour_second from E.StartDateTime )';
} elsif ( $term->{attr} eq 'Weekday' or $term->{attr} eq 'StartWeekday' ) { } elsif ( $term->{attr} eq 'Weekday' or $term->{attr} eq 'StartWeekday' ) {
$self->{Sql} .= 'weekday( E.StartTime )'; $self->{Sql} .= 'weekday( E.StartDateTime )';
# EndTIme options # EndTIme options
} elsif ( $term->{attr} eq 'EndDateTime' ) { } elsif ( $term->{attr} eq 'EndDateTime' ) {
$self->{Sql} .= 'E.EndTime'; $self->{Sql} .= 'E.EndDateTime';
} elsif ( $term->{attr} eq 'EndDate' ) { } elsif ( $term->{attr} eq 'EndDate' ) {
$self->{Sql} .= 'to_days( E.EndTime )'; $self->{Sql} .= 'to_days( E.EndDateTime )';
} elsif ( $term->{attr} eq 'EndTime' ) { } elsif ( $term->{attr} eq 'EndDateTime' ) {
$self->{Sql} .= 'extract( hour_second from E.EndTime )'; $self->{Sql} .= 'extract( hour_second from E.EndDateTime )';
} elsif ( $term->{attr} eq 'EndWeekday' ) { } elsif ( $term->{attr} eq 'EndWeekday' ) {
$self->{Sql} .= "weekday( E.EndTime )"; $self->{Sql} .= "weekday( E.EndDateTime )";
} elsif ( $term->{attr} eq 'ExistsInFileSystem' ) { } elsif ( $term->{attr} eq 'ExistsInFileSystem' ) {
push @{$self->{PostSQLConditions}}, $term; push @{$self->{PostSQLConditions}}, $term;
$self->{Sql} .= 'TRUE /* ExistsInFileSystem */'; $self->{Sql} .= 'TRUE /* ExistsInFileSystem */';
@ -368,7 +366,7 @@ sub Sql {
$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} = 'StartDateTime';
$filter_expr->{sort_asc} = 0; $filter_expr->{sort_asc} = 0;
} }
my $sort_column = ''; my $sort_column = '';
@ -378,10 +376,14 @@ sub Sql {
$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 'StartDateTime' ) {
$sort_column = 'E.StartDateTime';
} elsif ( $filter_expr->{sort_field} eq 'StartTime' ) { } elsif ( $filter_expr->{sort_field} eq 'StartTime' ) {
$sort_column = 'E.StartTime'; $sort_column = 'E.StartDateTime';
} elsif ( $filter_expr->{sort_field} eq 'EndTime' ) { } elsif ( $filter_expr->{sort_field} eq 'EndTime' ) {
$sort_column = 'E.EndTime'; $sort_column = 'E.EndDateTime';
} elsif ( $filter_expr->{sort_field} eq 'EndDateTime' ) {
$sort_column = 'E.EndDateTime';
} 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' ) {
@ -397,7 +399,7 @@ sub Sql {
} elsif ( $filter_expr->{sort_field} eq 'DiskSpace' ) { } elsif ( $filter_expr->{sort_field} eq 'DiskSpace' ) {
$sort_column = 'E.DiskSpace'; $sort_column = 'E.DiskSpace';
} else { } else {
$sort_column = 'E.StartTime'; $sort_column = 'E.StartDateTime';
} }
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;

View File

@ -262,21 +262,21 @@ sub createEvent {
} }
$frame->{Type} = $frame->{Score}>0?'Alarm':'Normal' unless( $frame->{Type} ); $frame->{Type} = $frame->{Score}>0?'Alarm':'Normal' unless( $frame->{Type} );
$frame->{Delta} = $lastTimestamp?($frame->{TimeStamp}-$lastTimestamp):0.0; $frame->{Delta} = $lastTimestamp?($frame->{TimeStamp}-$lastTimestamp):0.0;
$event->{StartTime} = $frame->{TimeStamp} unless ( $event->{StartTime} ); $event->{StartDateTime} = $frame->{TimeStamp} unless ( $event->{StartDateTime} );
$event->{TotScore} += $frame->{Score}; $event->{TotScore} += $frame->{Score};
$event->{MaxScore} = $frame->{Score} if ( $frame->{Score} > $event->{MaxScore} ); $event->{MaxScore} = $frame->{Score} if ( $frame->{Score} > $event->{MaxScore} );
$event->{AlarmFrames}++ if ( $frame->{Type} eq 'Alarm' ); $event->{AlarmFrames}++ if ( $frame->{Type} eq 'Alarm' );
$event->{EndTime} = $frame->{TimeStamp}; $event->{EndDateTime} = $frame->{TimeStamp};
$lastTimestamp = $frame->{TimeStamp}; $lastTimestamp = $frame->{TimeStamp};
} }
$event->{Width} = $event->{monitor}->{Width} unless( $event->{Width} ); $event->{Width} = $event->{monitor}->{Width} unless( $event->{Width} );
$event->{Height} = $event->{monitor}->{Height} unless( $event->{Height} ); $event->{Height} = $event->{monitor}->{Height} unless( $event->{Height} );
$event->{AvgScore} = $event->{TotScore}/int($event->{AlarmFrames}); $event->{AvgScore} = $event->{TotScore}/int($event->{AlarmFrames});
$event->{Length} = $event->{EndTime} - $event->{StartTime}; $event->{Length} = $event->{EndDateTime} - $event->{StartDateTime};
my %formats = ( my %formats = (
StartTime => 'from_unixtime(?)', StartDateTime => 'from_unixtime(?)',
EndTime => 'from_unixtime(?)', EndDateTime => 'from_unixtime(?)',
); );
my ( @fields, @formats, @values ); my ( @fields, @formats, @values );
@ -297,7 +297,7 @@ sub createEvent {
$event->{Id} = $dbh->{mysql_insertid}; $event->{Id} = $dbh->{mysql_insertid};
Info( "Created event ".$event->{Id} ); Info( "Created event ".$event->{Id} );
if ( $event->{EndTime} ) { if ( $event->{EndDateTime} ) {
$event->{Name} = $event->{monitor}->{EventPrefix}.$event->{Id} $event->{Name} = $event->{monitor}->{EventPrefix}.$event->{Id}
if ( $event->{Name} eq 'New Event' ); if ( $event->{Name} eq 'New Event' );
my $sql = "update Events set Name = ? where Id = ?"; my $sql = "update Events set Name = ? where Id = ?";
@ -383,8 +383,8 @@ sub updateEvent {
if ( $event->{Name} eq 'New Event' ); if ( $event->{Name} eq 'New Event' );
my %formats = ( my %formats = (
StartTime => 'from_unixtime(?)', StartDateTime => 'from_unixtime(?)',
EndTime => 'from_unixtime(?)', EndDateTime => 'from_unixtime(?)',
); );
my ( @values, @sets ); my ( @values, @sets );

View File

@ -504,9 +504,9 @@ sub openFile {
$LOGFILE->autoflush() if $this->{autoFlush}; $LOGFILE->autoflush() if $this->{autoFlush};
my $webUid = (getpwnam($ZoneMinder::Config::Config{ZM_WEB_USER}))[2]; my $webUid = (getpwnam($ZoneMinder::Config::Config{ZM_WEB_USER}))[2];
Error("Can't get uid for $ZoneMinder::Config::Config{ZM_WEB_USER}") if ! defined $webUid; Error('Can\'t get uid for '.$ZoneMinder::Config::Config{ZM_WEB_USER}) if ! defined $webUid;
my $webGid = (getgrnam($ZoneMinder::Config::Config{ZM_WEB_GROUP}))[2]; my $webGid = (getgrnam($ZoneMinder::Config::Config{ZM_WEB_GROUP}))[2];
Error("Can't get gid for $ZoneMinder::Config::Config{ZM_WEB_USER}") if ! defined $webGid; Error('Can\'t get gid for '.$ZoneMinder::Config::Config{ZM_WEB_USER}) if ! defined $webGid;
if ( $> == 0 ) { if ( $> == 0 ) {
# If we are root, we want to make sure that www-data or whatever owns the file # If we are root, we want to make sure that www-data or whatever owns the file
chown($webUid, $webGid, $this->{logFile} ) or chown($webUid, $webGid, $this->{logFile} ) or
@ -610,6 +610,7 @@ sub logInit( ;@ ) {
my %options = @_ ? @_ : (); my %options = @_ ? @_ : ();
$logger = ZoneMinder::Logger->new() if !$logger; $logger = ZoneMinder::Logger->new() if !$logger;
$logger->initialise(%options); $logger->initialise(%options);
logSetSignal();
} }
sub logReinit { sub logReinit {
@ -626,12 +627,26 @@ sub logHupHandler {
$do_log_rotate = 1; $do_log_rotate = 1;
} }
sub logUSR1Handler {
$logger->level($logger->level()+1);
Info('Logger - Level changed to '. $logger->level() . '=>'.$codes{$logger->level()});
}
sub logUSR2Handler {
$logger->level($logger->level()-1);
Info('Logger - Level changed to '. $logger->level() . '=>'.$codes{$logger->level()});
}
sub logSetSignal { sub logSetSignal {
$SIG{HUP} = \&logHupHandler; $SIG{HUP} = \&logHupHandler;
$SIG{USR1} = \&logUSR1Handler;
$SIG{USR2} = \&logUSR2Handler;
} }
sub logClearSignal { sub logClearSignal {
$SIG{HUP} = 'DEFAULT'; $SIG{HUP} = 'DEFAULT';
$SIG{USR1} = 'DEFAULT';
$SIG{USR2} = 'DEFAULT';
} }
sub logLevel { sub logLevel {

View File

@ -205,7 +205,7 @@ MAIN: while( $loop ) {
my $monitorSelectSth = $dbh->prepare_cached( $monitorSelectSql ) my $monitorSelectSth = $dbh->prepare_cached( $monitorSelectSql )
or Fatal( "Can't prepare '$monitorSelectSql': ".$dbh->errstr() ); or Fatal( "Can't prepare '$monitorSelectSql': ".$dbh->errstr() );
my $eventSelectSql = 'SELECT `Id`, (unix_timestamp() - unix_timestamp(`StartTime`)) AS Age my $eventSelectSql = 'SELECT `Id`, (unix_timestamp() - unix_timestamp(`StartDateTime`)) AS Age
FROM `Events` WHERE `MonitorId` = ?'.(@Storage_Areas ? ' AND `StorageId` IN ('.join(',',map { '?'} @Storage_Areas).')' : '' ). ' ORDER BY `Id`'; FROM `Events` WHERE `MonitorId` = ?'.(@Storage_Areas ? ' AND `StorageId` IN ('.join(',',map { '?'} @Storage_Areas).')' : '' ). ' ORDER BY `Id`';
my $eventSelectSth = $dbh->prepare_cached( $eventSelectSql ) my $eventSelectSth = $dbh->prepare_cached( $eventSelectSql )
or Fatal( "Can't prepare '$eventSelectSql': ".$dbh->errstr() ); or Fatal( "Can't prepare '$eventSelectSql': ".$dbh->errstr() );
@ -397,13 +397,13 @@ MAIN: while( $loop ) {
my ( undef, $year, $month, $day ) = split('/', $day_dir); my ( undef, $year, $month, $day ) = split('/', $day_dir);
$year += 2000; $year += 2000;
my ( $hour, $minute, $second ) = split('/', $event_dir); my ( $hour, $minute, $second ) = split('/', $event_dir);
my $StartTime =sprintf('%.4d-%.2d-%.2d %.2d:%.2d:%.2d', $year, $month, $day, $hour, $minute, $second); my $StartDateTime =sprintf('%.4d-%.2d-%.2d %.2d:%.2d:%.2d', $year, $month, $day, $hour, $minute, $second);
my $Event = ZoneMinder::Event->find_one( my $Event = ZoneMinder::Event->find_one(
MonitorId=>$monitor_dir, MonitorId=>$monitor_dir,
StartTime=>$StartTime, StartDateTime=>$StartDateTime,
); );
if ( $Event ) { if ( $Event ) {
Debug("Found event matching starttime on monitor $monitor_dir at $StartTime: " . $Event->to_string()); Debug("Found event matching StartDateTime on monitor $monitor_dir at $StartDateTime: " . $Event->to_string());
next; next;
} }
aud_print("Deleting event directories with no event id information at $day_dir/$event_dir"); aud_print("Deleting event directories with no event id information at $day_dir/$event_dir");
@ -440,7 +440,7 @@ MAIN: while( $loop ) {
$Event->Path(); $Event->Path();
$Event->age(); $Event->age();
Debug("Have event $$Event{Id} at $$Event{Path}"); Debug("Have event $$Event{Id} at $$Event{Path}");
$Event->StartTime(POSIX::strftime('%Y-%m-%d %H:%M:%S', gmtime(time_of_youngest_file($Event->Path())))); $Event->StartDateTime(POSIX::strftime('%Y-%m-%d %H:%M:%S', gmtime(time_of_youngest_file($Event->Path()))));
} # end foreach event } # end foreach event
} }
@ -592,7 +592,7 @@ EVENT: while ( my ( $db_event, $age ) = each( %$db_events ) ) {
Warning("Event $$Event{Id} is Archived. Taking no further action on it."); Warning("Event $$Event{Id} is Archived. Taking no further action on it.");
next; next;
} }
if ( !$Event->StartTime() ) { if ( !$Event->StartDateTime() ) {
aud_print("Event $$Event{Id} has no start time."); aud_print("Event $$Event{Id} has no start time.");
if ( confirm() ) { if ( confirm() ) {
$Event->delete(); $Event->delete();
@ -600,7 +600,7 @@ EVENT: while ( my ( $db_event, $age ) = each( %$db_events ) ) {
} }
next; next;
} }
if ( ! $Event->EndTime() ) { if ( ! $Event->EndDateTime() ) {
if ( $age > $Config{ZM_AUDIT_MIN_AGE} ) { if ( $age > $Config{ZM_AUDIT_MIN_AGE} ) {
aud_print("Event $$Event{Id} has no end time and is $age seconds old. Deleting it."); aud_print("Event $$Event{Id} has no end time and is $age seconds old. Deleting it.");
if ( confirm() ) { if ( confirm() ) {
@ -639,9 +639,9 @@ EVENT: while ( my ( $db_event, $age ) = each( %$db_events ) ) {
Info("Updating storage area on event $$Event{Id} from $$Event{StorageId} to $$fs_events{$db_event}{StorageId}"); Info("Updating storage area on event $$Event{Id} from $$Event{StorageId} to $$fs_events{$db_event}{StorageId}");
$Event->StorageId($$fs_events{$db_event}->StorageId()); $Event->StorageId($$fs_events{$db_event}->StorageId());
} }
if ( ! $Event->StartTime() ) { if ( ! $Event->StartDateTime() ) {
Info("Updating StartTime on event $$Event{Id} from $$Event{StartTime} to $$fs_events{$db_event}{StartTime}"); Info("Updating StartDateTime on event $$Event{Id} from $$Event{StartDateTime} to $$fs_events{$db_event}{StartDateTime}");
$Event->StartTime($$fs_events{$db_event}->StartTime()); $Event->StartDateTime($$fs_events{$db_event}->StartDateTime());
} }
$Event->save(); $Event->save();
@ -683,12 +683,12 @@ if ( $level > 1 ) {
# Remove empty events (with no frames) # Remove empty events (with no frames)
$cleaned = 0; $cleaned = 0;
Debug("Checking for Events with no Frames"); Debug("Checking for Events with no Frames");
my $selectEmptyEventsSql = 'SELECT `E`.`Id` AS `Id`, `E`.`StartTime`, `F`.`EventId` FROM `Events` AS E LEFT JOIN `Frames` AS F ON (`E`.`Id` = `F`.`EventId`) my $selectEmptyEventsSql = 'SELECT `E`.`Id` AS `Id`, `E`.`StartDateTime`, `F`.`EventId` FROM `Events` AS E LEFT JOIN `Frames` AS F ON (`E`.`Id` = `F`.`EventId`)
WHERE isnull(`F`.`EventId`) AND now() - interval '.$Config{ZM_AUDIT_MIN_AGE}.' second > `E`.`StartTime`'; WHERE isnull(`F`.`EventId`) AND now() - interval '.$Config{ZM_AUDIT_MIN_AGE}.' second > `E`.`StartDateTime`';
if ( my $selectEmptyEventsSth = $dbh->prepare_cached( $selectEmptyEventsSql ) ) { if ( my $selectEmptyEventsSth = $dbh->prepare_cached( $selectEmptyEventsSql ) ) {
if ( $res = $selectEmptyEventsSth->execute() ) { if ( $res = $selectEmptyEventsSth->execute() ) {
while( my $event = $selectEmptyEventsSth->fetchrow_hashref() ) { while( my $event = $selectEmptyEventsSth->fetchrow_hashref() ) {
aud_print("Found empty event with no frame records '$event->{Id}' at $$event{StartTime}"); aud_print("Found empty event with no frame records '$event->{Id}' at $$event{StartDateTime}");
if ( confirm() ) { if ( confirm() ) {
if ( $res = $deleteEventSth->execute($event->{Id}) ) { if ( $res = $deleteEventSth->execute($event->{Id}) ) {
$cleaned = 1; $cleaned = 1;
@ -750,7 +750,7 @@ if ( $level > 1 ) {
#"SELECT E.Id, ANY_VALUE(E.MonitorId), #"SELECT E.Id, ANY_VALUE(E.MonitorId),
# #
#max(F.TimeStamp) as EndTime, #max(F.TimeStamp) as EndTime,
#unix_timestamp(max(F.TimeStamp)) - unix_timestamp(E.StartTime) as Length, #unix_timestamp(max(F.TimeStamp)) - unix_timestamp(E.StartDateTime) as Length,
#max(F.FrameId) as Frames, #max(F.FrameId) as Frames,
#count(if(F.Score>0,1,NULL)) as AlarmFrames, #count(if(F.Score>0,1,NULL)) as AlarmFrames,
#sum(F.Score) as TotScore, #sum(F.Score) as TotScore,
@ -760,11 +760,11 @@ if ( $level > 1 ) {
#WHERE isnull(E.Frames) or isnull(E.EndTime) #WHERE isnull(E.Frames) or isnull(E.EndTime)
#GROUP BY E.Id HAVING EndTime < (now() - interval ".$Config{ZM_AUDIT_MIN_AGE}.' second)' #GROUP BY E.Id HAVING EndTime < (now() - interval ".$Config{ZM_AUDIT_MIN_AGE}.' second)'
#; #;
'SELECT *, unix_timestamp(`StartTime`) AS `TimeStamp` FROM `Events` WHERE `EndTime` IS NULL AND `StartTime` < (now() - interval '.$Config{ZM_AUDIT_MIN_AGE}.' second)'.($monitor_id?' AND MonitorId=?':''); 'SELECT *, unix_timestamp(`StartDateTime`) AS `TimeStamp` FROM `Events` WHERE `EndDateTime` IS NULL AND `StartDateTime` < (now() - interval '.$Config{ZM_AUDIT_MIN_AGE}.' second)'.($monitor_id?' AND MonitorId=?':'');
my $selectFrameDataSql = ' my $selectFrameDataSql = '
SELECT SELECT
max(`TimeStamp`) AS `EndTime`, max(`TimeStamp`) AS `EndDateTime`,
unix_timestamp(max(`TimeStamp`)) AS `EndTimeStamp`, unix_timestamp(max(`TimeStamp`)) AS `EndTimeStamp`,
max(`FrameId`) AS `Frames`, max(`FrameId`) AS `Frames`,
count(if(`Score`>0,1,NULL)) AS `AlarmFrames`, count(if(`Score`>0,1,NULL)) AS `AlarmFrames`,
@ -779,7 +779,7 @@ FROM `Frames` WHERE `EventId`=?';
my $updateUnclosedEventsSql = my $updateUnclosedEventsSql =
"UPDATE low_priority `Events` "UPDATE low_priority `Events`
SET `Name` = ?, SET `Name` = ?,
`EndTime` = ?, `EndDateTime` = ?,
`Length` = ?, `Length` = ?,
`Frames` = ?, `Frames` = ?,
`AlarmFrames` = ?, `AlarmFrames` = ?,
@ -794,7 +794,7 @@ FROM `Frames` WHERE `EventId`=?';
$res = $selectUnclosedEventsSth->execute($monitor_id?$monitor_id:()) $res = $selectUnclosedEventsSth->execute($monitor_id?$monitor_id:())
or Fatal("Can't execute: ".$selectUnclosedEventsSth->errstr()); or Fatal("Can't execute: ".$selectUnclosedEventsSth->errstr());
while( my $event = $selectUnclosedEventsSth->fetchrow_hashref() ) { while( my $event = $selectUnclosedEventsSth->fetchrow_hashref() ) {
aud_print("Found open event '$event->{Id}' on Monitor $event->{MonitorId} at $$event{StartTime}"); aud_print("Found open event '$event->{Id}' on Monitor $event->{MonitorId} at $$event{StartDateTime}");
if ( confirm('close', 'closing') ) { if ( confirm('close', 'closing') ) {
if ( ! ( $res = $selectFrameDataSth->execute($event->{Id}) ) ) { if ( ! ( $res = $selectFrameDataSth->execute($event->{Id}) ) ) {
Error("Can't execute: $selectFrameDataSql:".$selectFrameDataSth->errstr()); Error("Can't execute: $selectFrameDataSql:".$selectFrameDataSth->errstr());
@ -808,7 +808,7 @@ FROM `Frames` WHERE `EventId`=?';
$event->{Id}, $event->{Id},
RECOVER_TAG RECOVER_TAG
), ),
$frame->{EndTime}, $frame->{EndDateTime},
$frame->{EndTimeStamp} - $event->{TimeStamp}, $frame->{EndTimeStamp} - $event->{TimeStamp},
$frame->{Frames}, $frame->{Frames},
$frame->{AlarmFrames}, $frame->{AlarmFrames},

View File

@ -704,7 +704,7 @@ sub substituteTags {
$text =~ s/%EN%/$Event->{Name}/g; $text =~ s/%EN%/$Event->{Name}/g;
$text =~ s/%EC%/$Event->{Cause}/g; $text =~ s/%EC%/$Event->{Cause}/g;
$text =~ s/%ED%/$Event->{Notes}/g; $text =~ s/%ED%/$Event->{Notes}/g;
$text =~ s/%ET%/$Event->{StartTime}/g; $text =~ s/%ET%/$Event->{StartDateTime}/g;
$text =~ s/%EVF%/$$Event{DefaultVideo}/g; # Event video filename $text =~ s/%EVF%/$$Event{DefaultVideo}/g; # Event video filename
$text =~ s/%EL%/$Event->{Length}/g; $text =~ s/%EL%/$Event->{Length}/g;
$text =~ s/%EF%/$Event->{Frames}/g; $text =~ s/%EF%/$Event->{Frames}/g;

View File

@ -231,7 +231,7 @@ Debug("@Monitors");
$Event->Height( $Monitor->Height() ); $Event->Height( $Monitor->Height() );
$Event->Orientation( $Monitor->Orientation() ); $Event->Orientation( $Monitor->Orientation() );
$Event->recover_timestamps(); $Event->recover_timestamps();
if ( $$Event{StartTime} ) { if ( $$Event{StartDateTime} ) {
$Event->save({}, 1); $Event->save({}, 1);
Info("Event resurrected as " . $Event->to_string() ); Info("Event resurrected as " . $Event->to_string() );
} else { } else {
@ -294,7 +294,7 @@ Debug("@Monitors");
$Event->StorageId( $Storage->Id() ); $Event->StorageId( $Storage->Id() );
$Event->DiskSpace( undef ); $Event->DiskSpace( undef );
$Event->recover_timestamps(); $Event->recover_timestamps();
if ( $$Event{StartTime} ) { if ( $$Event{StartDateTime} ) {
$Event->save({}, 1); $Event->save({}, 1);
Info("Event resurrected as " . $Event->to_string() ); Info("Event resurrected as " . $Event->to_string() );
} else { } else {
@ -309,13 +309,13 @@ Debug("@Monitors");
my ( undef, $year, $month, $day ) = split('/', $day_dir); my ( undef, $year, $month, $day ) = split('/', $day_dir);
$year += 2000; $year += 2000;
my ( $hour, $minute, $second ) = split('/', $event_dir); my ( $hour, $minute, $second ) = split('/', $event_dir);
my $StartTime =sprintf('%.4d-%.2d-%.2d %.2d:%.2d:%.2d', $year, $month, $day, $hour, $minute, $second); my $StartDateTime =sprintf('%.4d-%.2d-%.2d %.2d:%.2d:%.2d', $year, $month, $day, $hour, $minute, $second);
my $Event = ZoneMinder::Event->find_one( my $Event = ZoneMinder::Event->find_one(
MonitorId=>$monitor_dir, MonitorId=>$monitor_dir,
StartTime=>$StartTime, StartDateTime=>$StartDateTime,
); );
if ( $Event ) { if ( $Event ) {
Debug("Found event matching starttime on monitor $monitor_dir at $StartTime: " . $Event->to_string()); Debug("Found event matching starttime on monitor $monitor_dir at $StartDateTime: " . $Event->to_string());
next; next;
} }
@ -358,7 +358,7 @@ Debug("@Monitors");
$Event->Orientation( $Monitor->Orientation() ); $Event->Orientation( $Monitor->Orientation() );
$Event->StorageId( $Storage->Id() ); $Event->StorageId( $Storage->Id() );
$Event->recover_timestamps(); $Event->recover_timestamps();
if ( $$Event{StartTime} ) { if ( $$Event{StartDateTime} ) {
$Event->save({}, 1); $Event->save({}, 1);
Info("Event resurrected as " . $Event->to_string() ); Info("Event resurrected as " . $Event->to_string() );
} else { } else {
@ -400,7 +400,7 @@ Debug("@Monitors");
$Event->Orientation( $Monitor->Orientation() ); $Event->Orientation( $Monitor->Orientation() );
$Event->StorageId( $Storage->Id() ); $Event->StorageId( $Storage->Id() );
$Event->recover_timestamps(); $Event->recover_timestamps();
if ( $$Event{StartTime} ) { if ( $$Event{StartDateTime} ) {
$Event->save({}, 1); $Event->save({}, 1);
Info("Event resurrected as " . $Event->to_string() ); Info("Event resurrected as " . $Event->to_string() );
} else { } else {

View File

@ -43,10 +43,10 @@ while( 1 ) {
} }
} }
$dbh->do('DELETE FROM Events_Hour WHERE StartTime < DATE_SUB(NOW(), INTERVAL 1 hour)') or Error($dbh->errstr()); $dbh->do('DELETE FROM Events_Hour WHERE StartDateTime < DATE_SUB(NOW(), INTERVAL 1 hour)') or Error($dbh->errstr());
$dbh->do('DELETE FROM Events_Day WHERE StartTime < DATE_SUB(NOW(), INTERVAL 1 day)') or Error($dbh->errstr()); $dbh->do('DELETE FROM Events_Day WHERE StartDateTime < DATE_SUB(NOW(), INTERVAL 1 day)') or Error($dbh->errstr());
$dbh->do('DELETE FROM Events_Week WHERE StartTime < DATE_SUB(NOW(), INTERVAL 1 week)') or Error($dbh->errstr()); $dbh->do('DELETE FROM Events_Week WHERE StartDateTime < DATE_SUB(NOW(), INTERVAL 1 week)') or Error($dbh->errstr());
$dbh->do('DELETE FROM Events_Month WHERE StartTime < DATE_SUB(NOW(), INTERVAL 1 month)') or Error($dbh->errstr()); $dbh->do('DELETE FROM Events_Month WHERE StartDateTime < DATE_SUB(NOW(), INTERVAL 1 month)') or Error($dbh->errstr());
# Prune the Logs table if required # Prune the Logs table if required
if ( $Config{ZM_LOG_DATABASE_LIMIT} ) { if ( $Config{ZM_LOG_DATABASE_LIMIT} ) {

View File

@ -201,7 +201,7 @@ if ( $event_id ) {
my $sql = " SELECT (SELECT max(Delta) FROM Frames WHERE EventId=Events.Id)-(SELECT min(Delta) FROM Frames WHERE EventId=Events.Id) as FullLength, my $sql = " SELECT (SELECT max(Delta) FROM Frames WHERE EventId=Events.Id)-(SELECT min(Delta) FROM Frames WHERE EventId=Events.Id) as FullLength,
Events.*, Events.*,
unix_timestamp(Events.StartTime) as Time, unix_timestamp(Events.StartDateTime) as Time,
M.Name as MonitorName, M.Name as MonitorName,
M.Palette M.Palette
FROM Events FROM Events

View File

@ -49,7 +49,7 @@ protected:
const int &mWd; const int &mWd;
protected: protected:
CommsBase( int &rd, int &wd ) : mRd( rd ), mWd( wd ) { CommsBase(const int &rd, const int &wd) : mRd(rd), mWd(wd) {
} }
virtual ~CommsBase() { virtual ~CommsBase() {
} }
@ -62,10 +62,10 @@ public:
public: public:
int getReadDesc() const { int getReadDesc() const {
return( mRd ); return mRd;
} }
int getWriteDesc() const { int getWriteDesc() const {
return( mWd ); return mWd;
} }
int getMaxDesc() const { int getMaxDesc() const {
return( mRd>mWd?mRd:mWd ); return( mRd>mWd?mRd:mWd );

View File

@ -112,8 +112,9 @@ public:
double DecimalValue() const; double DecimalValue() const;
const char *StringValue() const; const char *StringValue() const;
ConfigItem &operator=(const ConfigItem item) { ConfigItem &operator=(const ConfigItem &item) {
Copy(item);return *this; Copy(item);
return *this;
} }
inline operator bool() const { inline operator bool() const {
return BooleanValue(); return BooleanValue();

View File

@ -48,12 +48,12 @@ public:
return( result ); return( result );
} }
inline bool operator==( const Coord &coord ) { return( x == coord.x && y == coord.y ); } inline bool operator==( const Coord &coord ) const { return( x == coord.x && y == coord.y ); }
inline bool operator!=( const Coord &coord ) { return( x != coord.x || y != coord.y ); } inline bool operator!=( const Coord &coord ) const { return( x != coord.x || y != coord.y ); }
inline bool operator>( const Coord &coord ) { return( x > coord.x && y > coord.y ); } inline bool operator>( const Coord &coord ) const { return( x > coord.x && y > coord.y ); }
inline bool operator>=( const Coord &coord ) { return( !(operator<(coord)) ); } inline bool operator>=( const Coord &coord ) const { return( !(operator<(coord)) ); }
inline bool operator<( const Coord &coord ) { return( x < coord.x && y < coord.y ); } inline bool operator<( const Coord &coord ) const { return( x < coord.x && y < coord.y ); }
inline bool operator<=( const Coord &coord ) { return( !(operator>(coord)) ); } inline bool operator<=( const Coord &coord ) const { return( !(operator>(coord)) ); }
inline Coord &operator+=( const Coord &coord ) { x += coord.x; y += coord.y; return( *this ); } inline Coord &operator+=( const Coord &coord ) { x += coord.x; y += coord.y; return( *this ); }
inline Coord &operator-=( const Coord &coord ) { x -= coord.x; y -= coord.y; return( *this ); } inline Coord &operator-=( const Coord &coord ) { x -= coord.x; y -= coord.y; return( *this ); }

View File

@ -28,7 +28,7 @@ class zmDbRow {
MYSQL_RES *result_set; MYSQL_RES *result_set;
MYSQL_ROW row; MYSQL_ROW row;
public: public:
zmDbRow() { result_set = nullptr; row = nullptr; }; zmDbRow() : result_set(nullptr), row(nullptr) { };
MYSQL_RES *fetch( const char *query ); MYSQL_RES *fetch( const char *query );
zmDbRow( MYSQL_RES *, MYSQL_ROW *row ); zmDbRow( MYSQL_RES *, MYSQL_ROW *row );
~zmDbRow(); ~zmDbRow();

View File

@ -71,7 +71,7 @@ Event::Event(
start_time = now; start_time = now;
} else if ( start_time.tv_sec > now.tv_sec ) { } else if ( start_time.tv_sec > now.tv_sec ) {
Error( Error(
"StartTime in the future %u.%u > %u.%u", "StartDateTime in the future %u.%u > %u.%u",
start_time.tv_sec, start_time.tv_usec, now.tv_sec, now.tv_usec start_time.tv_sec, start_time.tv_usec, now.tv_sec, now.tv_usec
); );
start_time = now; start_time = now;
@ -88,7 +88,9 @@ Event::Event(
char sql[ZM_SQL_MED_BUFSIZ]; char sql[ZM_SQL_MED_BUFSIZ];
struct tm *stime = localtime(&start_time.tv_sec); struct tm *stime = localtime(&start_time.tv_sec);
snprintf(sql, sizeof(sql), "INSERT INTO Events ( MonitorId, StorageId, Name, StartTime, Width, Height, Cause, Notes, StateId, Orientation, Videoed, DefaultVideo, SaveJPEGs, Scheme ) VALUES ( %d, %d, 'New Event', from_unixtime( %ld ), %d, %d, '%s', '%s', %d, %d, %d, '%s', %d, '%s' )", snprintf(sql, sizeof(sql), "INSERT INTO Events "
"( MonitorId, StorageId, Name, StartDateTime, Width, Height, Cause, Notes, StateId, Orientation, Videoed, DefaultVideo, SaveJPEGs, Scheme )"
" VALUES ( %u, %u, 'New Event', from_unixtime( %ld ), %u, %u, '%s', '%s', %u, %d, %d, '%s', %d, '%s' )",
monitor->Id(), monitor->Id(),
storage->Id(), storage->Id(),
start_time.tv_sec, start_time.tv_sec,
@ -104,12 +106,10 @@ Event::Event(
storage->SchemeString().c_str() storage->SchemeString().c_str()
); );
db_mutex.lock(); db_mutex.lock();
if ( mysql_query(&dbconn, sql) ) { while ( mysql_query(&dbconn, sql) ) {
db_mutex.unlock(); db_mutex.unlock();
Error("Can't insert event: %s. sql was (%s)", mysql_error(&dbconn), sql); Error("Can't insert event: %s. sql was (%s)", mysql_error(&dbconn), sql);
return; db_mutex.lock();
} else {
Debug(2, "Created new event with %s", sql);
} }
id = mysql_insert_id(&dbconn); id = mysql_insert_id(&dbconn);
@ -254,6 +254,11 @@ Event::~Event() {
videowriter = nullptr; videowriter = nullptr;
} }
// endtime is set in AddFrame, so SHOULD be set to the value of the last frame timestamp.
if ( ! end_time.tv_sec ) {
Warning("Empty endtime for event. Should not happen. Setting to now.");
gettimeofday(&end_time, nullptr);
}
struct DeltaTimeval delta_time; struct DeltaTimeval delta_time;
DELTA_TIMEVAL(delta_time, end_time, start_time, DT_PREC_2); DELTA_TIMEVAL(delta_time, end_time, start_time, DT_PREC_2);
Debug(2, "start_time:%d.%d end_time%d.%d", start_time.tv_sec, start_time.tv_usec, end_time.tv_sec, end_time.tv_usec); Debug(2, "start_time:%d.%d end_time%d.%d", start_time.tv_sec, start_time.tv_usec, end_time.tv_sec, end_time.tv_usec);
@ -284,7 +289,7 @@ Event::~Event() {
// Should not be static because we might be multi-threaded // Should not be static because we might be multi-threaded
char sql[ZM_SQL_LGE_BUFSIZ]; char sql[ZM_SQL_LGE_BUFSIZ];
snprintf(sql, sizeof(sql), snprintf(sql, sizeof(sql),
"UPDATE Events SET Name='%s%" PRIu64 "', EndTime = from_unixtime(%ld), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64 " AND Name='New Event'", "UPDATE Events SET Name='%s%" PRIu64 "', EndDateTime = from_unixtime(%ld), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64 " AND Name='New Event'",
monitor->EventPrefix(), id, end_time.tv_sec, monitor->EventPrefix(), id, end_time.tv_sec,
delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec,
frames, alarm_frames, frames, alarm_frames,
@ -300,7 +305,7 @@ Event::~Event() {
if ( !mysql_affected_rows(&dbconn) ) { if ( !mysql_affected_rows(&dbconn) ) {
// Name might have been changed during recording, so just do the update without changing the name. // Name might have been changed during recording, so just do the update without changing the name.
snprintf(sql, sizeof(sql), snprintf(sql, sizeof(sql),
"UPDATE Events SET EndTime = from_unixtime(%ld), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64, "UPDATE Events SET EndDateTime = from_unixtime(%ld), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64,
end_time.tv_sec, end_time.tv_sec,
delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec,
frames, alarm_frames, frames, alarm_frames,
@ -334,7 +339,7 @@ bool Event::WriteFrameImage(
Image *image, Image *image,
struct timeval timestamp, struct timeval timestamp,
const char *event_file, const char *event_file,
bool alarm_frame) { bool alarm_frame) const {
int thisquality = int thisquality =
(alarm_frame && (config.jpeg_alarm_file_quality > config.jpeg_file_quality)) ? (alarm_frame && (config.jpeg_alarm_file_quality > config.jpeg_file_quality)) ?
@ -567,10 +572,12 @@ void Event::AddFramesInternal(int n_frames, int start_frame, Image **images, str
} else { } else {
Debug(1, "No valid pre-capture frames to add"); Debug(1, "No valid pre-capture frames to add");
} }
end_time = *timestamps[n_frames-1];
} // void Event::AddFramesInternal(int n_frames, int start_frame, Image **images, struct timeval **timestamps) } // void Event::AddFramesInternal(int n_frames, int start_frame, Image **images, struct timeval **timestamps)
void Event::WriteDbFrames() { void Event::WriteDbFrames() {
char *frame_insert_values_ptr = (char *)&frame_insert_sql + 90; // 90 == strlen(frame_insert_sql); char *frame_insert_values_ptr = (char *)&frame_insert_sql + 90; // 90 == strlen(frame_insert_sql);
Debug(1, "Inserting %d frames", frame_data.size());
while ( frame_data.size() ) { while ( frame_data.size() ) {
Frame *frame = frame_data.front(); Frame *frame = frame_data.front();
frame_data.pop(); frame_data.pop();
@ -586,8 +593,9 @@ void Event::WriteDbFrames() {
frame->score); frame->score);
delete frame; delete frame;
} }
*(frame_insert_values_ptr-1) = '\0'; // The -2 is for the extra , added for values above *(frame_insert_values_ptr-1) = '\0'; // The -1 is for the extra , added for values above
db_mutex.lock(); db_mutex.lock();
Debug(1, "SQL: %s", frame_insert_sql);
int rc = mysql_query(&dbconn, frame_insert_sql); int rc = mysql_query(&dbconn, frame_insert_sql);
db_mutex.unlock(); db_mutex.unlock();
@ -682,7 +690,6 @@ void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *a
bool db_frame = ( frame_type != BULK ) || (frames==1) || ((frames%config.bulk_frame_interval)==0) ; bool db_frame = ( frame_type != BULK ) || (frames==1) || ((frames%config.bulk_frame_interval)==0) ;
if ( db_frame ) { if ( db_frame ) {
static char sql[ZM_SQL_MED_BUFSIZ];
// The idea is to write out 1/sec // The idea is to write out 1/sec
frame_data.push(new Frame(id, frames, frame_type, timestamp, delta_time, score)); frame_data.push(new Frame(id, frames, frame_type, timestamp, delta_time, score));
@ -692,6 +699,7 @@ void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *a
WriteDbFrames(); WriteDbFrames();
last_db_frame = frames; last_db_frame = frames;
static char sql[ZM_SQL_MED_BUFSIZ];
snprintf(sql, sizeof(sql), snprintf(sql, sizeof(sql),
"UPDATE Events SET Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64, "UPDATE Events SET Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64,
( delta_time.positive?"":"-" ), ( delta_time.positive?"":"-" ),

View File

@ -113,23 +113,21 @@ class Event {
~Event(); ~Event();
uint64_t Id() const { return id; } uint64_t Id() const { return id; }
const std::string &Cause() { return cause; } const std::string &Cause() const { return cause; }
int Frames() const { return frames; } int Frames() const { return frames; }
int AlarmFrames() const { return alarm_frames; } int AlarmFrames() const { return alarm_frames; }
const struct timeval &StartTime() const { return start_time; } const struct timeval &StartTime() const { return start_time; }
const struct timeval &EndTime() const { return end_time; } const struct timeval &EndTime() const { return end_time; }
struct timeval &StartTime() { return start_time; }
struct timeval &EndTime() { return end_time; }
bool SendFrameImage( const Image *image, bool alarm_frame=false ); bool SendFrameImage( const Image *image, bool alarm_frame=false );
bool WriteFrameImage( Image *image, struct timeval timestamp, const char *event_file, bool alarm_frame=false ); bool WriteFrameImage( Image *image, struct timeval timestamp, const char *event_file, bool alarm_frame=false ) const;
bool WriteFrameVideo( const Image *image, const struct timeval timestamp, VideoWriter* videow ); bool WriteFrameVideo( const Image *image, const struct timeval timestamp, VideoWriter* videow );
void updateNotes( const StringSetMap &stringSetMap ); void updateNotes( const StringSetMap &stringSetMap );
void AddFrames( int n_frames, Image **images, struct timeval **timestamps ); void AddFrames( int n_frames, Image **images, struct timeval **timestamps );
void AddFrame( Image *image, struct timeval timestamp, int score=0, Image *alarm_frame=nullptr ); void AddFrame( Image *image, struct timeval timestamp, int score=0, Image *alarm_image=nullptr );
private: private:
void AddFramesInternal( int n_frames, int start_frame, Image **images, struct timeval **timestamps ); void AddFramesInternal( int n_frames, int start_frame, Image **images, struct timeval **timestamps );
@ -146,7 +144,7 @@ class Event {
return Event::getSubPath( localtime( time ) ); return Event::getSubPath( localtime( time ) );
} }
const char* getEventFile(void) { const char* getEventFile(void) const {
return video_file.c_str(); return video_file.c_str();
} }

View File

@ -45,7 +45,7 @@ bool EventStream::loadInitialEventData(int monitor_id, time_t event_time) {
static char sql[ZM_SQL_SML_BUFSIZ]; static char sql[ZM_SQL_SML_BUFSIZ];
snprintf(sql, sizeof(sql), "SELECT `Id` FROM `Events` WHERE " snprintf(sql, sizeof(sql), "SELECT `Id` FROM `Events` WHERE "
"`MonitorId` = %d AND unix_timestamp(`EndTime`) > %ld " "`MonitorId` = %d AND unix_timestamp(`EndDateTime`) > %ld "
"ORDER BY `Id` ASC LIMIT 1", monitor_id, event_time); "ORDER BY `Id` ASC LIMIT 1", monitor_id, event_time);
if ( mysql_query(&dbconn, sql) ) { if ( mysql_query(&dbconn, sql) ) {
@ -116,8 +116,8 @@ bool EventStream::loadEventData(uint64_t event_id) {
static char sql[ZM_SQL_MED_BUFSIZ]; static char sql[ZM_SQL_MED_BUFSIZ];
snprintf(sql, sizeof(sql), snprintf(sql, sizeof(sql),
"SELECT `MonitorId`, `StorageId`, `Frames`, unix_timestamp( `StartTime` ) AS StartTimestamp, " "SELECT `MonitorId`, `StorageId`, `Frames`, unix_timestamp( `StartDateTime` ) AS StartTimestamp, "
"unix_timestamp( `EndTime` ) AS EndTimestamp, " "unix_timestamp( `EndDateTime` ) AS EndTimestamp, "
"(SELECT max(`Delta`)-min(`Delta`) FROM `Frames` WHERE `EventId`=`Events`.`Id`) AS Duration, " "(SELECT max(`Delta`)-min(`Delta`) FROM `Frames` WHERE `EventId`=`Events`.`Id`) AS Duration, "
"`DefaultVideo`, `Scheme`, `SaveJPEGs`, `Orientation`+0 FROM `Events` WHERE `Id` = %" PRIu64, event_id); "`DefaultVideo`, `Scheme`, `SaveJPEGs`, `Orientation`+0 FROM `Events` WHERE `Id` = %" PRIu64, event_id);
@ -189,13 +189,13 @@ bool EventStream::loadEventData(uint64_t event_id) {
if ( storage_path[0] == '/' ) if ( storage_path[0] == '/' )
snprintf(event_data->path, sizeof(event_data->path), snprintf(event_data->path, sizeof(event_data->path),
"%s/%d/%02d/%02d/%02d/%02d/%02d/%02d", "%s/%u/%02d/%02d/%02d/%02d/%02d/%02d",
storage_path, event_data->monitor_id, storage_path, event_data->monitor_id,
event_time->tm_year-100, event_time->tm_mon+1, event_time->tm_mday, event_time->tm_year-100, event_time->tm_mon+1, event_time->tm_mday,
event_time->tm_hour, event_time->tm_min, event_time->tm_sec); event_time->tm_hour, event_time->tm_min, event_time->tm_sec);
else else
snprintf(event_data->path, sizeof(event_data->path), snprintf(event_data->path, sizeof(event_data->path),
"%s/%s/%d/%02d/%02d/%02d/%02d/%02d/%02d", "%s/%s/%u/%02d/%02d/%02d/%02d/%02d/%02d",
staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id, staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id,
event_time->tm_year-100, event_time->tm_mon+1, event_time->tm_mday, event_time->tm_year-100, event_time->tm_mon+1, event_time->tm_mday,
event_time->tm_hour, event_time->tm_min, event_time->tm_sec); event_time->tm_hour, event_time->tm_min, event_time->tm_sec);
@ -203,23 +203,23 @@ bool EventStream::loadEventData(uint64_t event_id) {
struct tm *event_time = localtime(&event_data->start_time); struct tm *event_time = localtime(&event_data->start_time);
if ( storage_path[0] == '/' ) if ( storage_path[0] == '/' )
snprintf(event_data->path, sizeof(event_data->path), snprintf(event_data->path, sizeof(event_data->path),
"%s/%d/%04d-%02d-%02d/%" PRIu64, "%s/%u/%04d-%02d-%02d/%" PRIu64,
storage_path, event_data->monitor_id, storage_path, event_data->monitor_id,
event_time->tm_year+1900, event_time->tm_mon+1, event_time->tm_mday, event_time->tm_year+1900, event_time->tm_mon+1, event_time->tm_mday,
event_data->event_id); event_data->event_id);
else else
snprintf(event_data->path, sizeof(event_data->path), snprintf(event_data->path, sizeof(event_data->path),
"%s/%s/%d/%04d-%02d-%02d/%" PRIu64, "%s/%s/%u/%04d-%02d-%02d/%" PRIu64,
staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id, staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id,
event_time->tm_year+1900, event_time->tm_mon+1, event_time->tm_mday, event_time->tm_year+1900, event_time->tm_mon+1, event_time->tm_mday,
event_data->event_id); event_data->event_id);
} else { } else {
if ( storage_path[0] == '/' ) if ( storage_path[0] == '/' )
snprintf(event_data->path, sizeof(event_data->path), "%s/%d/%" PRIu64, snprintf(event_data->path, sizeof(event_data->path), "%s/%u/%" PRIu64,
storage_path, event_data->monitor_id, event_data->event_id); storage_path, event_data->monitor_id, event_data->event_id);
else else
snprintf(event_data->path, sizeof(event_data->path), "%s/%s/%d/%" PRIu64, snprintf(event_data->path, sizeof(event_data->path), "%s/%s/%u/%" PRIu64,
staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id, staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id,
event_data->event_id); event_data->event_id);
} }
@ -424,6 +424,7 @@ void EventStream::processCommand(const CmdMsg *msg) {
switch ( replay_rate ) { switch ( replay_rate ) {
case -1 * ZM_RATE_BASE : case -1 * ZM_RATE_BASE :
replay_rate = -2 * ZM_RATE_BASE; replay_rate = -2 * ZM_RATE_BASE;
break;
case -2 * ZM_RATE_BASE : case -2 * ZM_RATE_BASE :
replay_rate = -5 * ZM_RATE_BASE; replay_rate = -5 * ZM_RATE_BASE;
break; break;
@ -526,7 +527,7 @@ void EventStream::processCommand(const CmdMsg *msg) {
if ( offset < 0.0 ) { if ( offset < 0.0 ) {
Warning("Invalid offset, not seeking"); Warning("Invalid offset, not seeking");
break; break;
} }
// This should get us close, but not all frames will have the same duration // This should get us close, but not all frames will have the same duration
curr_frame_id = (int)(event_data->frame_count*offset/event_data->duration)+1; curr_frame_id = (int)(event_data->frame_count*offset/event_data->duration)+1;
if ( event_data->frames[curr_frame_id-1].offset > offset ) { if ( event_data->frames[curr_frame_id-1].offset > offset ) {
@ -538,10 +539,10 @@ void EventStream::processCommand(const CmdMsg *msg) {
} }
if ( curr_frame_id < 1 ) { if ( curr_frame_id < 1 ) {
curr_frame_id = 1; curr_frame_id = 1;
} else if ( curr_frame_id > event_data->last_frame_id ) { } else if ( (unsigned long)curr_frame_id > event_data->last_frame_id ) {
curr_frame_id = event_data->last_frame_id; curr_frame_id = event_data->last_frame_id;
} }
curr_stream_time = event_data->frames[curr_frame_id-1].timestamp; curr_stream_time = event_data->frames[curr_frame_id-1].timestamp;
Debug(1, "Got SEEK command, to %f (new current frame id: %d offset %f)", Debug(1, "Got SEEK command, to %f (new current frame id: %d offset %f)",
offset, curr_frame_id, event_data->frames[curr_frame_id-1].offset); offset, curr_frame_id, event_data->frames[curr_frame_id-1].offset);
@ -794,7 +795,7 @@ bool EventStream::sendFrame(int delta_us) {
Error("Unable to get a frame"); Error("Unable to get a frame");
return false; return false;
} }
Image *send_image = prepareImage(image); Image *send_image = prepareImage(image);
static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE]; static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE];
int img_buffer_size = 0; int img_buffer_size = 0;
@ -881,7 +882,7 @@ void EventStream::runStream() {
// If we are streaming and this frame is due to be sent // If we are streaming and this frame is due to be sent
// frame mod defaults to 1 and if we are going faster than max_fps will get multiplied by 2 // frame mod defaults to 1 and if we are going faster than max_fps will get multiplied by 2
// so if it is 2, then we send every other frame, if is it 4 then every fourth frame, etc. // so if it is 2, then we send every other frame, if is it 4 then every fourth frame, etc.
if ( (frame_mod == 1) || (((curr_frame_id-1)%frame_mod) == 0) ) { if ( (frame_mod == 1) || (((curr_frame_id-1)%frame_mod) == 0) ) {
send_frame = true; send_frame = true;
} }
@ -963,7 +964,7 @@ void EventStream::runStream() {
if ( (mode == MODE_SINGLE) && ( if ( (mode == MODE_SINGLE) && (
(curr_frame_id < 1 ) (curr_frame_id < 1 )
|| ||
((unsigned int)curr_frame_id >= event_data->frame_count) ((unsigned int)curr_frame_id >= event_data->frame_count)
) )
) { ) {
Debug(2, "Have mode==MODE_SINGLE and at end of event, looping back to start"); Debug(2, "Have mode==MODE_SINGLE and at end of event, looping back to start");
@ -1054,9 +1055,8 @@ void EventStream::runStream() {
closeComms(); closeComms();
} // end void EventStream::runStream() } // end void EventStream::runStream()
bool EventStream::send_file(const char * filepath) { bool EventStream::send_file(const char *filepath) {
static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE]; static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE];
int rc;
int img_buffer_size = 0; int img_buffer_size = 0;
uint8_t *img_buffer = temp_img_buffer; uint8_t *img_buffer = temp_img_buffer;
@ -1084,7 +1084,7 @@ bool EventStream::send_file(const char * filepath) {
Info("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno)); Info("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno));
return false; return false;
} }
rc = zm_sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size); int rc = zm_sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size);
if ( rc == (int)filestat.st_size ) { if ( rc == (int)filestat.st_size ) {
// Success // Success
fclose(fdj); /* Close the file handle */ fclose(fdj); /* Close the file handle */

View File

@ -76,7 +76,7 @@ class EventStream : public StreamBase {
StreamMode mode; StreamMode mode;
bool forceEventChange; bool forceEventChange;
unsigned long curr_frame_id; long curr_frame_id;
double curr_stream_time; double curr_stream_time;
bool send_frame; bool send_frame;
struct timeval start; // clock time when started the event struct timeval start; // clock time when started the event
@ -133,11 +133,11 @@ class EventStream : public StreamBase {
void setStreamMode( StreamMode p_mode ) { void setStreamMode( StreamMode p_mode ) {
mode = p_mode; mode = p_mode;
} }
void runStream(); void runStream() override;
Image *getImage(); Image *getImage();
private: private:
bool send_file( const char *file_path ); bool send_file(const char *filepath);
bool send_buffer( uint8_t * buffer, int size ); bool send_buffer(uint8_t * buffer, int size);
Storage *storage; Storage *storage;
FFmpeg_Input *ffmpeg_input; FFmpeg_Input *ffmpeg_input;
AVCodecContext *input_codec_context; AVCodecContext *input_codec_context;

View File

@ -22,8 +22,7 @@
#include <string> #include <string>
class Exception class Exception {
{
protected: protected:
typedef enum { INFO, WARNING, ERROR, FATAL } Severity; typedef enum { INFO, WARNING, ERROR, FATAL } Severity;
@ -32,33 +31,28 @@ protected:
Severity mSeverity; Severity mSeverity;
public: public:
Exception( const std::string &message, Severity severity=ERROR ) : mMessage( message ), mSeverity( severity ) explicit Exception(const std::string &message, const Severity severity=ERROR) :
mMessage(message),
mSeverity(severity)
{ {
} }
public: const std::string &getMessage() const {
const std::string &getMessage() const return mMessage;
{
return( mMessage );
} }
Severity getSeverity() const Severity getSeverity() const {
{ return mSeverity;
return( mSeverity );
} }
bool isInfo() const bool isInfo() const {
{ return mSeverity == INFO;
return( mSeverity == INFO );
} }
bool isWarning() const bool isWarning() const {
{
return( mSeverity == WARNING ); return( mSeverity == WARNING );
} }
bool isError() const bool isError() const {
{
return( mSeverity == ERROR ); return( mSeverity == ERROR );
} }
bool isFatal() const bool isFatal() const {
{
return( mSeverity == FATAL ); return( mSeverity == FATAL );
} }
}; };

View File

@ -23,10 +23,10 @@ class FFmpeg_Input {
int Close(); int Close();
AVFrame *get_frame( int stream_id=-1 ); AVFrame *get_frame( int stream_id=-1 );
AVFrame *get_frame( int stream_id, double at ); AVFrame *get_frame( int stream_id, double at );
int get_video_stream_id() { int get_video_stream_id() const {
return video_stream_id; return video_stream_id;
} }
int get_audio_stream_id() { int get_audio_stream_id() const {
return audio_stream_id; return audio_stream_id;
} }

View File

@ -68,19 +68,26 @@ class FifoStream : public StreamBase {
); );
protected: protected:
typedef enum { MJPEG, RAW } StreamType; typedef enum { UNKNOWN, MJPEG, RAW } StreamType;
StreamType stream_type; StreamType stream_type;
bool sendMJEGFrames(); bool sendMJEGFrames();
bool sendRAWFrames(); bool sendRAWFrames();
void processCommand(const CmdMsg *msg) {} void processCommand(const CmdMsg *msg) {}
public: public:
FifoStream() {} FifoStream() :
stream_path(nullptr),
fd(0),
total_read(0),
bytes_read(0),
frame_count(0),
stream_type(UNKNOWN)
{}
static void fifo_create_if_missing( static void fifo_create_if_missing(
const char * path, const char * path,
bool delete_fake_fifo = true); bool delete_fake_fifo = true);
void setStreamStart(const char * path); void setStreamStart(const char * path);
void setStreamStart(int monitor_id, const char * format); void setStreamStart(int monitor_id, const char * format);
void runStream(); void runStream() override;
}; };
#endif // ZM_FIFO_H #endif // ZM_FIFO_H

View File

@ -153,17 +153,17 @@ public:
int Palette() const { return( palette ); } int Palette() const { return( palette ); }
int Extras() const { return( extras ); } int Extras() const { return( extras ); }
int Brightness( int p_brightness=-1 ); int Brightness( int p_brightness=-1 ) override;
int Hue( int p_hue=-1 ); int Hue( int p_hue=-1 ) override;
int Colour( int p_colour=-1 ); int Colour( int p_colour=-1 ) override;
int Contrast( int p_contrast=-1 ); int Contrast( int p_contrast=-1 ) override;
int PrimeCapture(); int PrimeCapture()override ;
int PreCapture(); int PreCapture()override ;
int Capture( Image &image ); int Capture( Image &image )override ;
int PostCapture(); int PostCapture()override ;
int CaptureAndRecord( Image &image, timeval recording, char* event_directory ) {return(0);}; int CaptureAndRecord( Image &image, timeval recording, char* event_directory ) override {return(0);};
int Close() { return 0; }; int Close() override { return 0; };
static bool GetCurrentSettings( const char *device, char *output, int version, bool verbose ); static bool GetCurrentSettings( const char *device, char *output, int version, bool verbose );
}; };

View File

@ -43,18 +43,6 @@ Logger *Logger::smInstance = nullptr;
Logger::StringMap Logger::smCodes; Logger::StringMap Logger::smCodes;
Logger::IntMap Logger::smSyslogPriorities; Logger::IntMap Logger::smSyslogPriorities;
#if 0
static void subtractTime( struct timeval * const tp1, struct timeval * const tp2 ) {
tp1->tv_sec -= tp2->tv_sec;
if ( tp1->tv_usec <= tp2->tv_usec ) {
tp1->tv_sec--;
tp1->tv_usec = 1000000 - (tp2->tv_usec - tp1->tv_usec);
} else {
tp1->tv_usec = tp1->tv_usec - tp2->tv_usec;
}
}
#endif
void Logger::usrHandler(int sig) { void Logger::usrHandler(int sig) {
Logger *logger = fetch(); Logger *logger = fetch();
if ( sig == SIGUSR1 ) if ( sig == SIGUSR1 )

View File

@ -121,7 +121,7 @@ private:
Logger(); Logger();
~Logger(); ~Logger();
int limit(int level) { int limit(const int level) const {
if ( level > DEBUG9 ) if ( level > DEBUG9 )
return DEBUG9; return DEBUG9;
if ( level < NOLOG ) if ( level < NOLOG )
@ -163,7 +163,7 @@ public:
} }
Level level(Level=NOOPT); Level level(Level=NOOPT);
bool debugOn() { bool debugOn() const {
return mEffectiveLevel >= DEBUG1; return mEffectiveLevel >= DEBUG1;
} }

View File

@ -26,7 +26,7 @@
inline void* zm_mallocaligned(unsigned int reqalignment, size_t reqsize) { inline void* zm_mallocaligned(unsigned int reqalignment, size_t reqsize) {
uint8_t* retptr; uint8_t* retptr;
#if HAVE_POSIX_MEMALIGN #if HAVE_POSIX_MEMALIGN
if ( posix_memalign((void**)&retptr,reqalignment,reqsize) != 0 ) if ( posix_memalign((void**)&retptr, reqalignment, reqsize) != 0 )
return nullptr; return nullptr;
return retptr; return retptr;
@ -39,7 +39,7 @@ inline void* zm_mallocaligned(unsigned int reqalignment, size_t reqsize) {
alloc = retptr + sizeof(void*); alloc = retptr + sizeof(void*);
if(((long)alloc % reqalignment) != 0) if ( ((long)alloc % reqalignment) != 0 )
alloc = alloc + (reqalignment - ((long)alloc % reqalignment)); alloc = alloc + (reqalignment - ((long)alloc % reqalignment));
/* Store a pointer before to the start of the block, just before returned aligned memory */ /* Store a pointer before to the start of the block, just before returned aligned memory */

View File

@ -1613,7 +1613,6 @@ bool Monitor::Analyse() {
} // end if analysis_fps && pre_event_count } // end if analysis_fps && pre_event_count
shared_data->last_event = event->Id(); shared_data->last_event = event->Id();
//set up video store data
snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile()); snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile());
video_store_data->recording = event->StartTime(); video_store_data->recording = event->StartTime();
@ -2654,10 +2653,6 @@ bool Monitor::closeEvent() {
if ( !event ) if ( !event )
return false; return false;
if ( function == RECORD || function == MOCORD ) {
//FIXME Is this neccessary? ENdTime should be set in the destructor
gettimeofday(&(event->EndTime()), nullptr);
}
if ( event_delete_thread ) { if ( event_delete_thread ) {
event_delete_thread->join(); event_delete_thread->join();
delete event_delete_thread; delete event_delete_thread;

View File

@ -444,7 +444,7 @@ public:
inline Function GetFunction() const { inline Function GetFunction() const {
return( function ); return( function );
} }
inline bool Enabled() { inline bool Enabled() const {
if ( function <= MONITOR ) if ( function <= MONITOR )
return false; return false;
return enabled; return enabled;
@ -452,17 +452,17 @@ public:
inline const char *EventPrefix() const { inline const char *EventPrefix() const {
return event_prefix; return event_prefix;
} }
inline bool Ready() { inline bool Ready() const {
if ( function <= MONITOR ) if ( function <= MONITOR )
return false; return false;
return( image_count > ready_count ); return( image_count > ready_count );
} }
inline bool Active() { inline bool Active() const {
if ( function <= MONITOR ) if ( function <= MONITOR )
return false; return false;
return( enabled && shared_data->active ); return( enabled && shared_data->active );
} }
inline bool Exif() { inline bool Exif() const {
return embed_exif; return embed_exif;
} }
Orientation getOrientation() const; Orientation getOrientation() const;
@ -479,7 +479,7 @@ public:
uint64_t GetVideoWriterEventId() const { return video_store_data->current_event; } uint64_t GetVideoWriterEventId() const { return video_store_data->current_event; }
void SetVideoWriterEventId( unsigned long long p_event_id ) { video_store_data->current_event = p_event_id; } void SetVideoWriterEventId( unsigned long long p_event_id ) { video_store_data->current_event = p_event_id; }
struct timeval GetVideoWriterStartTime() const { return video_store_data->recording; } struct timeval GetVideoWriterStartTime() const { return video_store_data->recording; }
void SetVideoWriterStartTime(struct timeval &t) { video_store_data->recording = t; } void SetVideoWriterStartTime(const struct timeval &t) { video_store_data->recording = t; }
unsigned int GetPreEventCount() const { return pre_event_count; }; unsigned int GetPreEventCount() const { return pre_event_count; };
struct timeval GetVideoBufferDuration() const { return video_buffer_duration; }; struct timeval GetVideoBufferDuration() const { return video_buffer_duration; };
@ -505,7 +505,7 @@ public:
inline time_t getStartupTime() const { return shared_data->startup_time; } inline time_t getStartupTime() const { return shared_data->startup_time; }
inline void setStartupTime( time_t p_time ) { shared_data->startup_time = p_time; } inline void setStartupTime( time_t p_time ) { shared_data->startup_time = p_time; }
int LabelSize() { return label_size; } int LabelSize() const { return label_size; }
void actionReload(); void actionReload();
void actionEnable(); void actionEnable();

View File

@ -292,7 +292,7 @@ void MonitorStream::processCommand(const CmdMsg *msg) {
if ( (nbytes = sendto(sd, &status_msg, sizeof(status_msg), MSG_DONTWAIT, (sockaddr *)&rem_addr, sizeof(rem_addr))) < 0 ) { if ( (nbytes = sendto(sd, &status_msg, sizeof(status_msg), MSG_DONTWAIT, (sockaddr *)&rem_addr, sizeof(rem_addr))) < 0 ) {
//if ( errno != EAGAIN ) //if ( errno != EAGAIN )
{ {
Error( "Can't sendto on sd %d: %s", sd, strerror(errno) ); Error("Can't sendto on sd %d: %s", sd, strerror(errno));
//exit( -1 ); //exit( -1 );
} }
} }
@ -503,7 +503,7 @@ void MonitorStream::runStream() {
const int max_swap_len_suffix = 15; const int max_swap_len_suffix = 15;
int swap_path_length = staticConfig.PATH_SWAP.length() + 1; // +1 for NULL terminator int swap_path_length = staticConfig.PATH_SWAP.length() + 1; // +1 for NULL terminator
int subfolder1_length = snprintf(nullptr, 0, "/zmswap-m%d", monitor->Id()) + 1; int subfolder1_length = snprintf(nullptr, 0, "/zmswap-m%u", monitor->Id()) + 1;
int subfolder2_length = snprintf(nullptr, 0, "/zmswap-q%06d", connkey) + 1; int subfolder2_length = snprintf(nullptr, 0, "/zmswap-q%06d", connkey) + 1;
int total_swap_path_length = swap_path_length + subfolder1_length + subfolder2_length; int total_swap_path_length = swap_path_length + subfolder1_length + subfolder2_length;
@ -874,7 +874,7 @@ void MonitorStream::SingleImageRaw(int scale) {
} }
fprintf(stdout, fprintf(stdout,
"Content-Length: %d\r\n" "Content-Length: %u\r\n"
"Content-Type: image/x-rgb\r\n\r\n", "Content-Type: image/x-rgb\r\n\r\n",
snap_image->Size()); snap_image->Size());
fwrite(snap_image->Buffer(), snap_image->Size(), 1, stdout); fwrite(snap_image->Buffer(), snap_image->Size(), 1, stdout);

View File

@ -71,7 +71,7 @@ class MonitorStream : public StreamBase {
bool setStreamStart(int monitor_id) { bool setStreamStart(int monitor_id) {
return loadMonitor(monitor_id); return loadMonitor(monitor_id);
} }
void runStream(); void runStream() override;
}; };
#endif // ZM_MONITORSTREAM_H #endif // ZM_MONITORSTREAM_H

View File

@ -31,7 +31,7 @@ extern "C" {
} }
class zm_packetqueue { class zm_packetqueue {
public: public:
zm_packetqueue(int max_stream_id); explicit zm_packetqueue(int max_stream_id);
virtual ~zm_packetqueue(); virtual ~zm_packetqueue();
bool queuePacket(AVPacket* packet, struct timeval *timestamp); bool queuePacket(AVPacket* packet, struct timeval *timestamp);
bool queuePacket(ZMPacket* packet); bool queuePacket(ZMPacket* packet);

View File

@ -29,15 +29,13 @@
bool zm_reload = false; bool zm_reload = false;
bool zm_terminate = false; bool zm_terminate = false;
RETSIGTYPE zm_hup_handler(int signal) RETSIGTYPE zm_hup_handler(int signal) {
{
// Shouldn't do complex things in signal handlers, logging is complex and can block due to mutexes. // Shouldn't do complex things in signal handlers, logging is complex and can block due to mutexes.
//Info("Got signal %d (%s), reloading", signal, strsignal(signal)); //Info("Got signal %d (%s), reloading", signal, strsignal(signal));
zm_reload = true; zm_reload = true;
} }
RETSIGTYPE zm_term_handler(int signal) RETSIGTYPE zm_term_handler(int signal) {
{
// Shouldn't do complex things in signal handlers, logging is complex and can block due to mutexes. // Shouldn't do complex things in signal handlers, logging is complex and can block due to mutexes.
//Info("Got signal %d (%s), exiting", signal, strsignal(signal)); //Info("Got signal %d (%s), exiting", signal, strsignal(signal));
zm_terminate = true; zm_terminate = true;
@ -55,8 +53,7 @@ RETSIGTYPE zm_die_handler(int signal)
#if ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) #if ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T )
void *ip = nullptr; void *ip = nullptr;
void *cr2 = nullptr; void *cr2 = nullptr;
if (info && context) { if ( info && context ) {
Debug(1, Debug(1,
"Signal information: number %d code %d errno %d pid %d uid %d status %d", "Signal information: number %d code %d errno %d pid %d uid %d status %d",
signal, info->si_code, info->si_errno, info->si_pid, signal, info->si_code, info->si_errno, info->si_pid,
@ -79,7 +76,7 @@ RETSIGTYPE zm_die_handler(int signal)
#endif // defined(__x86_64__) #endif // defined(__x86_64__)
// Print the signal address and instruction pointer if available // Print the signal address and instruction pointer if available
if (ip) { if ( ip ) {
Error("Signal address is %p, from %p", cr2, ip); Error("Signal address is %p, from %p", cr2, ip);
} else { } else {
Error("Signal address is %p, no instruction pointer", cr2); Error("Signal address is %p, no instruction pointer", cr2);
@ -115,8 +112,7 @@ RETSIGTYPE zm_die_handler(int signal)
exit(signal); exit(signal);
} }
void zmSetHupHandler(SigHandler * handler) void zmSetHupHandler(SigHandler * handler) {
{
sigset_t block_set; sigset_t block_set;
sigemptyset(&block_set); sigemptyset(&block_set);
struct sigaction action, old_action; struct sigaction action, old_action;
@ -127,8 +123,7 @@ void zmSetHupHandler(SigHandler * handler)
sigaction(SIGHUP, &action, &old_action); sigaction(SIGHUP, &action, &old_action);
} }
void zmSetTermHandler(SigHandler * handler) void zmSetTermHandler(SigHandler * handler) {
{
sigset_t block_set; sigset_t block_set;
sigemptyset(&block_set); sigemptyset(&block_set);
struct sigaction action, old_action; struct sigaction action, old_action;
@ -141,8 +136,7 @@ void zmSetTermHandler(SigHandler * handler)
sigaction(SIGQUIT, &action, &old_action); sigaction(SIGQUIT, &action, &old_action);
} }
void zmSetDieHandler(SigHandler * handler) void zmSetDieHandler(SigHandler * handler) {
{
sigset_t block_set; sigset_t block_set;
sigemptyset(&block_set); sigemptyset(&block_set);
struct sigaction action, old_action; struct sigaction action, old_action;
@ -163,19 +157,16 @@ void zmSetDieHandler(SigHandler * handler)
sigaction(SIGFPE, &action, &old_action); sigaction(SIGFPE, &action, &old_action);
} }
void zmSetDefaultHupHandler() void zmSetDefaultHupHandler() {
{
zmSetHupHandler((SigHandler *) zm_hup_handler); zmSetHupHandler((SigHandler *) zm_hup_handler);
} }
void zmSetDefaultTermHandler() void zmSetDefaultTermHandler() {
{
zmSetTermHandler((SigHandler *) zm_term_handler); zmSetTermHandler((SigHandler *) zm_term_handler);
} }
void zmSetDefaultDieHandler() void zmSetDefaultDieHandler() {
{ if ( config.dump_cores ) {
if (config.dump_cores) {
// Do nothing // Do nothing
} else { } else {
zmSetDieHandler((SigHandler *) zm_die_handler); zmSetDieHandler((SigHandler *) zm_die_handler);

View File

@ -76,7 +76,9 @@ struct DeltaTimeval
#define USEC_PER_SEC 1000000 #define USEC_PER_SEC 1000000
#define MSEC_PER_SEC 1000 #define MSEC_PER_SEC 1000
/*
extern struct timeval tv; extern struct timeval tv;
*/
inline int tvDiffUsec( struct timeval first, struct timeval last ) inline int tvDiffUsec( struct timeval first, struct timeval last )
{ {

View File

@ -46,7 +46,7 @@ class User {
User(); User();
explicit User(const MYSQL_ROW &dbrow); explicit User(const MYSQL_ROW &dbrow);
~User(); ~User();
User(User &u) { Copy(u); } User(const User &u) { Copy(u); }
void Copy(const User &u); void Copy(const User &u);
User& operator=(const User &u) { User& operator=(const User &u) {
Copy(u); return *this; Copy(u); return *this;

View File

@ -216,7 +216,7 @@ int X264MP4Writer::Open() {
int X264MP4Writer::Close() { int X264MP4Writer::Close() {
/* Flush all pending frames */ /* Flush all pending frames */
for ( int i = (x264_encoder_delayed_frames(x264enc) + 1); i > 0; i-- ) { for ( int i = (x264_encoder_delayed_frames(x264enc) + 1); i > 0; i-- ) {
Debug(1,"Encoding delayed frame"); Debug(1, "Encoding delayed frame");
if ( x264encodeloop(true) < 0 ) if ( x264encodeloop(true) < 0 )
break; break;
} }
@ -227,7 +227,7 @@ Debug(1,"Encoding delayed frame");
/* Close MP4 handle */ /* Close MP4 handle */
MP4Close(mp4h); MP4Close(mp4h);
Debug(1,"Optimising"); Debug(1, "Optimising");
/* Required for proper HTTP streaming */ /* Required for proper HTTP streaming */
MP4Optimize((path + ".incomplete").c_str(), path.c_str()); MP4Optimize((path + ".incomplete").c_str(), path.c_str());

View File

@ -95,91 +95,92 @@ int main(int argc, const char *argv[], char **envp) {
} }
const char *query = getenv("QUERY_STRING"); const char *query = getenv("QUERY_STRING");
if ( query ) { if ( query == nullptr ) {
Debug(1, "Query: %s", query);
char temp_query[1024];
strncpy(temp_query, query, sizeof(temp_query)-1);
char *q_ptr = temp_query;
char *parms[16]; // Shouldn't be more than this
int parm_no = 0;
while ( (parm_no < 16) && (parms[parm_no] = strtok(q_ptr, "&")) ) {
parm_no++;
q_ptr = nullptr;
}
for ( int p = 0; p < parm_no; p++ ) {
char *name = strtok(parms[p], "=");
char const *value = strtok(nullptr, "=");
if ( !value )
value = "";
if ( !strcmp(name, "source") ) {
source = !strcmp(value, "event")?ZMS_EVENT:ZMS_MONITOR;
if ( !strcmp(value, "fifo") )
source = ZMS_FIFO;
} else if ( !strcmp(name, "mode") ) {
mode = !strcmp(value, "jpeg")?ZMS_JPEG:ZMS_MPEG;
mode = !strcmp(value, "raw")?ZMS_RAW:mode;
mode = !strcmp(value, "zip")?ZMS_ZIP:mode;
mode = !strcmp(value, "single")?ZMS_SINGLE:mode;
} else if ( !strcmp(name, "format") ) {
strncpy( format, value, sizeof(format) );
} else if ( !strcmp(name, "monitor") ) {
monitor_id = atoi(value);
if ( source == ZMS_UNKNOWN )
source = ZMS_MONITOR;
} else if ( !strcmp(name, "time") ) {
event_time = atoi(value);
} else if ( !strcmp(name, "event") ) {
event_id = strtoull(value, nullptr, 10);
source = ZMS_EVENT;
} else if ( !strcmp(name, "frame") ) {
frame_id = strtoull(value, nullptr, 10);
source = ZMS_EVENT;
} else if ( !strcmp(name, "scale") ) {
scale = atoi(value);
} else if ( !strcmp(name, "rate") ) {
rate = atoi(value);
} else if ( !strcmp(name, "maxfps") ) {
maxfps = atof(value);
} else if ( !strcmp(name, "bitrate") ) {
bitrate = atoi(value);
} else if ( !strcmp(name, "ttl") ) {
ttl = atoi(value);
} else if ( !strcmp(name, "replay") ) {
if ( !strcmp(value, "gapless") ) {
replay = EventStream::MODE_ALL_GAPLESS;
} else if ( !strcmp(value, "all") ) {
replay = EventStream::MODE_ALL;
} else if ( !strcmp(value, "none") ) {
replay = EventStream::MODE_NONE;
} else if ( !strcmp(value, "single") ) {
replay = EventStream::MODE_SINGLE;
} else {
Error("Unsupported value %s for replay, defaulting to none", value);
}
} else if ( !strcmp(name, "connkey") ) {
connkey = atoi(value);
} else if ( !strcmp(name, "buffer") ) {
playback_buffer = atoi(value);
} else if ( !strcmp(name, "auth") ) {
strncpy(auth, value, sizeof(auth)-1);
} else if ( !strcmp(name, "token") ) {
jwt_token_str = value;
Debug(1, "ZMS: JWT token found: %s", jwt_token_str.c_str());
} else if ( !strcmp(name, "user") ) {
username = UriDecode(value);
} else if ( !strcmp(name, "pass") ) {
password = UriDecode(value);
Debug(1, "Have %s for password", password.c_str());
} else {
Debug(1, "Unknown parameter passed to zms %s=%s", name, value);
} // end if possible parameter names
} // end foreach parm
} else {
Fatal("No query string."); Fatal("No query string.");
return 0;
} // end if query } // end if query
Debug(1, "Query: %s", query);
char temp_query[1024];
strncpy(temp_query, query, sizeof(temp_query)-1);
char *q_ptr = temp_query;
char *parms[16]; // Shouldn't be more than this
int parm_no = 0;
while ( (parm_no < 16) && (parms[parm_no] = strtok(q_ptr, "&")) ) {
parm_no++;
q_ptr = nullptr;
}
for ( int p = 0; p < parm_no; p++ ) {
char *name = strtok(parms[p], "=");
char const *value = strtok(nullptr, "=");
if ( !value )
value = "";
if ( !strcmp(name, "source") ) {
source = !strcmp(value, "event")?ZMS_EVENT:ZMS_MONITOR;
if ( !strcmp(value, "fifo") )
source = ZMS_FIFO;
} else if ( !strcmp(name, "mode") ) {
mode = !strcmp(value, "jpeg")?ZMS_JPEG:ZMS_MPEG;
mode = !strcmp(value, "raw")?ZMS_RAW:mode;
mode = !strcmp(value, "zip")?ZMS_ZIP:mode;
mode = !strcmp(value, "single")?ZMS_SINGLE:mode;
} else if ( !strcmp(name, "format") ) {
strncpy(format, value, sizeof(format)-1);
} else if ( !strcmp(name, "monitor") ) {
monitor_id = atoi(value);
if ( source == ZMS_UNKNOWN )
source = ZMS_MONITOR;
} else if ( !strcmp(name, "time") ) {
event_time = atoi(value);
} else if ( !strcmp(name, "event") ) {
event_id = strtoull(value, nullptr, 10);
source = ZMS_EVENT;
} else if ( !strcmp(name, "frame") ) {
frame_id = strtoull(value, nullptr, 10);
source = ZMS_EVENT;
} else if ( !strcmp(name, "scale") ) {
scale = atoi(value);
} else if ( !strcmp(name, "rate") ) {
rate = atoi(value);
} else if ( !strcmp(name, "maxfps") ) {
maxfps = atof(value);
} else if ( !strcmp(name, "bitrate") ) {
bitrate = atoi(value);
} else if ( !strcmp(name, "ttl") ) {
ttl = atoi(value);
} else if ( !strcmp(name, "replay") ) {
if ( !strcmp(value, "gapless") ) {
replay = EventStream::MODE_ALL_GAPLESS;
} else if ( !strcmp(value, "all") ) {
replay = EventStream::MODE_ALL;
} else if ( !strcmp(value, "none") ) {
replay = EventStream::MODE_NONE;
} else if ( !strcmp(value, "single") ) {
replay = EventStream::MODE_SINGLE;
} else {
Error("Unsupported value %s for replay, defaulting to none", value);
}
} else if ( !strcmp(name, "connkey") ) {
connkey = atoi(value);
} else if ( !strcmp(name, "buffer") ) {
playback_buffer = atoi(value);
} else if ( !strcmp(name, "auth") ) {
strncpy(auth, value, sizeof(auth)-1);
} else if ( !strcmp(name, "token") ) {
jwt_token_str = value;
Debug(1, "ZMS: JWT token found: %s", jwt_token_str.c_str());
} else if ( !strcmp(name, "user") ) {
username = UriDecode(value);
} else if ( !strcmp(name, "pass") ) {
password = UriDecode(value);
Debug(1, "Have %s for password", password.c_str());
} else {
Debug(1, "Unknown parameter passed to zms %s=%s", name, value);
} // end if possible parameter names
} // end foreach parm
if ( monitor_id ) { if ( monitor_id ) {
snprintf(log_id_string, sizeof(log_id_string), "zms_m%d", monitor_id); snprintf(log_id_string, sizeof(log_id_string), "zms_m%d", monitor_id);
} else { } else {

View File

@ -482,7 +482,7 @@ int main(int argc, char *argv[]) {
} // end if ! MONITOR } // end if ! MONITOR
if ( verbose ) { if ( verbose ) {
printf("Monitor %d(%s)\n", monitor->Id(), monitor->Name()); printf("Monitor %u(%s)\n", monitor->Id(), monitor->Name());
} }
if ( !monitor->connect() ) { if ( !monitor->connect() ) {
Error("Can't connect to capture daemon: %d %s", monitor->Id(), monitor->Name()); Error("Can't connect to capture daemon: %d %s", monitor->Id(), monitor->Name());
@ -521,19 +521,19 @@ int main(int argc, char *argv[]) {
} }
if ( function & ZMU_READ_IDX ) { if ( function & ZMU_READ_IDX ) {
if ( verbose ) if ( verbose )
printf("Last read index: %d\n", monitor->GetLastReadIndex()); printf("Last read index: %u\n", monitor->GetLastReadIndex());
else { else {
if ( have_output ) fputc(separator, stdout); if ( have_output ) fputc(separator, stdout);
printf("%d", monitor->GetLastReadIndex()); printf("%u", monitor->GetLastReadIndex());
have_output = true; have_output = true;
} }
} }
if ( function & ZMU_WRITE_IDX ) { if ( function & ZMU_WRITE_IDX ) {
if ( verbose ) { if ( verbose ) {
printf("Last write index: %d\n", monitor->GetLastWriteIndex()); printf("Last write index: %u\n", monitor->GetLastWriteIndex());
} else { } else {
if ( have_output ) fputc(separator, stdout); if ( have_output ) fputc(separator, stdout);
printf("%d", monitor->GetLastWriteIndex()); printf("%u", monitor->GetLastWriteIndex());
have_output = true; have_output = true;
} }
} }
@ -558,9 +558,9 @@ int main(int argc, char *argv[]) {
if ( function & ZMU_IMAGE ) { if ( function & ZMU_IMAGE ) {
if ( verbose ) { if ( verbose ) {
if ( image_idx == -1 ) if ( image_idx == -1 )
printf("Dumping last image captured to Monitor%d.jpg", monitor->Id()); printf("Dumping last image captured to Monitor%u.jpg", monitor->Id());
else else
printf("Dumping buffer image %d to Monitor%d.jpg", image_idx, monitor->Id()); printf("Dumping buffer image %d to Monitor%u.jpg", image_idx, monitor->Id());
if ( scale != -1 ) if ( scale != -1 )
printf(", scaling by %d%%", scale); printf(", scaling by %d%%", scale);
printf("\n"); printf("\n");
@ -569,7 +569,7 @@ int main(int argc, char *argv[]) {
} }
if ( function & ZMU_ZONES ) { if ( function & ZMU_ZONES ) {
if ( verbose ) if ( verbose )
printf("Dumping zone image to Zones%d.jpg\n", monitor->Id()); printf("Dumping zone image to Zones%u.jpg\n", monitor->Id());
monitor->DumpZoneImage(zoneString); monitor->DumpZoneImage(zoneString);
} }
if ( function & ZMU_ALARM ) { if ( function & ZMU_ALARM ) {
@ -735,17 +735,17 @@ int main(int argc, char *argv[]) {
Debug(1, "Got %d monitors", mysql_num_rows(result)); Debug(1, "Got %d monitors", mysql_num_rows(result));
printf("%4s%5s%6s%9s%14s%6s%6s%8s%8s\n", "Id", "Func", "State", "TrgState", "LastImgTim", "RdIdx", "WrIdx", "LastEvt", "FrmRate"); printf("%4s%5s%6s%9s%14s%6s%6s%8s%8s\n", "Id", "Func", "State", "TrgState", "LastImgTim", "RdIdx", "WrIdx", "LastEvt", "FrmRate");
for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row(result); i++ ) { for ( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row(result); i++ ) {
int mon_id = atoi(dbrow[0]); int monitor_id = atoi(dbrow[0]);
int function = atoi(dbrow[1]); int monitor_function = atoi(dbrow[1]);
if ( !user || user->canAccess(mon_id) ) { if ( !user || user->canAccess(monitor_id) ) {
if ( function > 1 ) { if ( monitor_function > 1 ) {
Monitor *monitor = Monitor::Load(mon_id, false, Monitor::QUERY); Monitor *monitor = Monitor::Load(monitor_id, false, Monitor::QUERY);
if ( monitor && monitor->connect() ) { if ( monitor && monitor->connect() ) {
struct timeval tv = monitor->GetTimestamp(); struct timeval tv = monitor->GetTimestamp();
printf( "%4d%5d%6d%9d%11ld.%02ld%6d%6d%8" PRIu64 "%8.2f\n", printf( "%4d%5d%6d%9d%11ld.%02ld%6d%6d%8" PRIu64 "%8.2f\n",
monitor->Id(), monitor->Id(),
function, monitor_function,
monitor->GetState(), monitor->GetState(),
monitor->GetTriggerState(), monitor->GetTriggerState(),
tv.tv_sec, tv.tv_usec/10000, tv.tv_sec, tv.tv_usec/10000,

View File

@ -1 +1 @@
1.35.12 1.35.13

View File

@ -39,7 +39,7 @@ $search = isset($_REQUEST['search']) ? $_REQUEST['search'] : '';
$advsearch = isset($_REQUEST['advsearch']) ? json_decode($_REQUEST['advsearch'], JSON_OBJECT_AS_ARRAY) : array(); $advsearch = isset($_REQUEST['advsearch']) ? json_decode($_REQUEST['advsearch'], JSON_OBJECT_AS_ARRAY) : array();
// Sort specifies the name of the column to sort on // Sort specifies the name of the column to sort on
$sort = 'StartTime'; $sort = 'StartDateTime';
if ( isset($_REQUEST['sort']) ) { if ( isset($_REQUEST['sort']) ) {
$sort = $_REQUEST['sort']; $sort = $_REQUEST['sort'];
} }
@ -133,7 +133,7 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim
$table = 'Events'; $table = 'Events';
// The names of the dB columns in the events table we are interested in // The names of the dB columns in the events table we are interested in
$columns = array('Id', 'MonitorId', 'StorageId', 'Name', 'Cause', 'StartTime', 'EndTime', 'Length', 'Frames', 'AlarmFrames', 'TotScore', 'AvgScore', 'MaxScore', 'Archived', 'Emailed', 'Notes', 'DiskSpace'); $columns = array('Id', 'MonitorId', 'StorageId', 'Name', 'Cause', 'StartDateTime', 'EndDateTime', 'Length', 'Frames', 'AlarmFrames', 'TotScore', 'AvgScore', 'MaxScore', 'Archived', 'Emailed', 'Notes', 'DiskSpace');
// The names of columns shown in the event view that are NOT dB columns in the database // The names of columns shown in the event view that are NOT dB columns in the database
$col_alt = array('Monitor', 'Storage'); $col_alt = array('Monitor', 'Storage');
@ -212,19 +212,24 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim
$row['Archived'] = $row['Archived'] ? translate('Yes') : translate('No'); $row['Archived'] = $row['Archived'] ? translate('Yes') : translate('No');
$row['Emailed'] = $row['Emailed'] ? translate('Yes') : translate('No'); $row['Emailed'] = $row['Emailed'] ? translate('Yes') : translate('No');
$row['Cause'] = validHtmlStr($row['Cause']); $row['Cause'] = validHtmlStr($row['Cause']);
$row['StartTime'] = strftime(STRF_FMT_DATETIME_SHORTER, strtotime($row['StartTime'])); $row['StartDateTime'] = strftime(STRF_FMT_DATETIME_SHORTER, strtotime($row['StartDateTime']));
$row['EndTime'] = strftime(STRF_FMT_DATETIME_SHORTER, strtotime($row['EndTime'])); $row['EndDateTime'] = $row['EndDateTime'] ? strftime(STRF_FMT_DATETIME_SHORTER, strtotime($row['EndDateTime'])) : null;
$row['Length'] = gmdate('H:i:s', $row['Length'] ); $row['Length'] = gmdate('H:i:s', $row['Length'] );
$row['Storage'] = ( $row['StorageId'] and isset($StorageById[$row['StorageId']]) ) ? $StorageById[$row['StorageId']]->Name() : 'Default'; $row['Storage'] = ( $row['StorageId'] and isset($StorageById[$row['StorageId']]) ) ? $StorageById[$row['StorageId']]->Name() : 'Default';
$row['Notes'] = htmlspecialchars($row['Notes']); $row['Notes'] = nl2br(htmlspecialchars($row['Notes']));
$row['DiskSpace'] = human_filesize($event->DiskSpace()); $row['DiskSpace'] = human_filesize($event->DiskSpace());
$rows[] = $row; $rows[] = $row;
} }
$data['rows'] = $rows; $data['rows'] = $rows;
# total has to be the # of available rows. Not sure what totalNotFiltered is actually used for yet. # totalNotFiltered must equal total, except when either search bar has been used
$data['totalNotFiltered'] = $data['total'] = dbFetchOne('SELECT count(*) AS Total FROM ' .$table. ' AS E'. ($filter->sql() ? ' WHERE '.$filter->sql():''), 'Total'); $data['totalNotFiltered'] = dbFetchOne('SELECT count(*) AS Total FROM Events AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id'. ($filter->sql() ? ' WHERE '.$filter->sql():''), 'Total');
#$data['total'] = count($rows); if ( $search != '' || count($advsearch) ) {
$data['total'] = dbFetchOne('SELECT count(*) AS Total FROM Events AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id'.$where , 'Total', $wherevalues);
} else {
$data['total'] = $data['totalNotFiltered'];
}
return $data; return $data;
} }
?> ?>

View File

@ -14,8 +14,8 @@ class Event extends ZM_Object {
'StorageId' => null, 'StorageId' => null,
'SecondaryStorageId' => null, 'SecondaryStorageId' => null,
'Cause' => '', 'Cause' => '',
'StartTime' => null, 'StartDateTime' => null,
'EndTime' => null, 'EndDateTime' => null,
'Width' => null, 'Width' => null,
'Height' => null, 'Height' => null,
'Length' => null, 'Length' => null,
@ -93,7 +93,7 @@ class Event extends ZM_Object {
public function Time() { public function Time() {
if ( ! isset($this->{'Time'}) ) { if ( ! isset($this->{'Time'}) ) {
$this->{'Time'} = strtotime($this->{'StartTime'}); $this->{'Time'} = strtotime($this->{'StartDateTime'});
} }
return $this->{'Time'}; return $this->{'Time'};
} }
@ -153,9 +153,9 @@ class Event extends ZM_Object {
if ( $this->{'Scheme'} == 'Deep' ) { if ( $this->{'Scheme'} == 'Deep' ) {
# Assumption: All events have a start time # Assumption: All events have a start time
$start_date = date_parse($this->{'StartTime'}); $start_date = date_parse($this->{'StartDateTime'});
if ( ! $start_date ) { if ( ! $start_date ) {
throw new Exception('Unable to parse start time for event ' . $this->{'Id'} . ' not deleting files.'); throw new Exception('Unable to parse start date time for event ' . $this->{'Id'} . ' not deleting files.');
} }
$start_date['year'] = $start_date['year'] % 100; $start_date['year'] = $start_date['year'] % 100;
@ -279,7 +279,7 @@ class Event extends ZM_Object {
} }
if ( (!property_exists($this, 'DiskSpace')) or (null === $this->{'DiskSpace'}) ) { if ( (!property_exists($this, 'DiskSpace')) or (null === $this->{'DiskSpace'}) ) {
$this->{'DiskSpace'} = folder_size($this->Path()); $this->{'DiskSpace'} = folder_size($this->Path());
if ( $this->{'EndTime'} ) { if ( $this->{'EndDateTime'} ) {
# Finished events shouldn't grow in size much so we can commit it to the db. # Finished events shouldn't grow in size much so we can commit it to the db.
dbQuery('UPDATE Events SET DiskSpace=? WHERE Id=?', array($this->{'DiskSpace'}, $this->{'Id'})); dbQuery('UPDATE Events SET DiskSpace=? WHERE Id=?', array($this->{'DiskSpace'}, $this->{'Id'}));
} }
@ -606,7 +606,7 @@ class Event extends ZM_Object {
if ( $this->Archived() ) { if ( $this->Archived() ) {
return false; return false;
} }
if ( !$this->EndTime() ) { if ( !$this->EndDateTime() ) {
return false; return false;
} }
if ( !canEdit('Events') ) { if ( !canEdit('Events') ) {
@ -619,7 +619,7 @@ class Event extends ZM_Object {
public function cant_delete_reason() { public function cant_delete_reason() {
if ( $this->Archived() ) { if ( $this->Archived() ) {
return 'You cannot delete an archived event. Unarchive it first.'; return 'You cannot delete an archived event. Unarchive it first.';
} else if ( ! $this->EndTime() ) { } else if ( ! $this->EndDateTime() ) {
return 'You cannot delete an event while it is being recorded. Wait for it to finish.'; return 'You cannot delete an event while it is being recorded. Wait for it to finish.';
} else if ( ! canEdit('Events') ) { } else if ( ! canEdit('Events') ) {
return 'You do not have rights to edit Events.'; return 'You do not have rights to edit Events.';

View File

@ -1,6 +1,7 @@
<?php <?php
namespace ZM; namespace ZM;
require_once('Object.php'); require_once('Object.php');
require_once('FilterTerm.php');
class Filter extends ZM_Object { class Filter extends ZM_Object {
protected static $table = 'Filters'; protected static $table = 'Filters';
@ -60,7 +61,7 @@ class Filter extends ZM_Object {
$this->_querystring .= $term->querystring($objectname, $separator); $this->_querystring .= $term->querystring($objectname, $separator);
} # end foreach term } # end foreach term
if ( $this->Id() ) { if ( $this->Id() ) {
$this->_querystring .= $separator.$objectname.'[Id]='.$this->Id(); $this->_querystring .= $separator.$objectname.urlencode('[Id]=').$this->Id();
} }
} }
return $this->_querystring; return $this->_querystring;
@ -391,35 +392,35 @@ class Filter extends ZM_Object {
break; break;
case 'DateTime': case 'DateTime':
case 'StartDateTime': case 'StartDateTime':
$sqlValue = 'E.StartTime'; $sqlValue = 'E.StartDateTime';
$dtAttr = true; $dtAttr = true;
break; break;
case 'Date': case 'Date':
case 'StartDate': case 'StartDate':
$sqlValue = 'to_days(E.StartTime)'; $sqlValue = 'to_days(E.StartDateTime)';
$dtAttr = true; $dtAttr = true;
break; break;
case 'Time': case 'Time':
case 'StartTime': case 'StartTime':
$sqlValue = 'extract(hour_second from E.StartTime)'; $sqlValue = 'extract(hour_second from E.StartDateTime)';
break; break;
case 'Weekday': case 'Weekday':
case 'StartWeekday': case 'StartWeekday':
$sqlValue = 'weekday(E.StartTime)'; $sqlValue = 'weekday(E.StartDateTime)';
break; break;
case 'EndDateTime': case 'EndDateTime':
$sqlValue = 'E.EndTime'; $sqlValue = 'E.EndDateTime';
$dtAttr = true; $dtAttr = true;
break; break;
case 'EndDate': case 'EndDate':
$sqlValue = 'to_days(E.EndTime)'; $sqlValue = 'to_days(E.EndDateTime)';
$dtAttr = true; $dtAttr = true;
break; break;
case 'EndTime': case 'EndTime':
$sqlValue = 'extract(hour_second from E.EndTime)'; $sqlValue = 'extract(hour_second from E.EndDateTime)';
break; break;
case 'EndWeekday': case 'EndWeekday':
$sqlValue = 'weekday(E.EndTime)'; $sqlValue = 'weekday(E.EndDateTime)';
break; break;
case 'Id': case 'Id':
case 'Name': case 'Name':
@ -632,6 +633,11 @@ class Filter extends ZM_Object {
function addTerm($term=false, $position=null) { function addTerm($term=false, $position=null) {
if ( !FilterTerm::is_valid_attr($term['attr']) ) {
Error('Unsupported filter attribute ' . $term['attr']);
return $this;
}
$terms = $this->terms(); $terms = $this->terms();
if ( (!isset($position)) or ($position > count($terms)) ) if ( (!isset($position)) or ($position > count($terms)) )
@ -650,5 +656,12 @@ class Filter extends ZM_Object {
return $this; return $this;
} # end function addTerm } # end function addTerm
function addTerms($terms, $options=null) {
foreach ( $terms as $term ) {
$this->addTerm($term);
}
return $this;
}
} # end class Filter } # end class Filter
?> ?>

View File

@ -13,6 +13,7 @@ function getFilterQueryConjunctionTypes() {
return $validConjunctionTypes; return $validConjunctionTypes;
} }
class FilterTerm { class FilterTerm {
public $filter; public $filter;
public $index; public $index;
@ -35,7 +36,7 @@ class FilterTerm {
$this->val = $term['val']; $this->val = $term['val'];
if ( isset($term['cnj']) ) { if ( isset($term['cnj']) ) {
if ( array_key_exists($term['cnj'], $validConjunctionTypes) ) { if ( array_key_exists($term['cnj'], $validConjunctionTypes) ) {
$this->cnj = $term['cnj']; $this->cnj = $term['cnj'];
} else { } else {
Warning('Invalid cnj ' . $term['cnj'].' in '.print_r($term, true)); Warning('Invalid cnj ' . $term['cnj'].' in '.print_r($term, true));
} }
@ -65,7 +66,8 @@ class FilterTerm {
return $values; return $values;
} }
foreach ( preg_split('/["\'\s]*?,["\'\s]*?/', preg_replace('/^["\']+?(.+)["\']+?$/', '$1', $this->val)) as $value ) { $vals = is_array($this->val) ? $this->val : preg_split('/["\'\s]*?,["\'\s]*?/', preg_replace('/^["\']+?(.+)["\']+?$/', '$1', $this->val));
foreach ( $vals as $value ) {
switch ( $this->attr ) { switch ( $this->attr ) {
@ -75,7 +77,7 @@ class FilterTerm {
case 'ExistsInFileSystem': case 'ExistsInFileSystem':
$value = ''; $value = '';
break; break;
case 'DiskSpace': case 'DiskPercent':
$value = ''; $value = '';
break; break;
case 'MonitorName': case 'MonitorName':
@ -83,7 +85,7 @@ class FilterTerm {
case 'Name': case 'Name':
case 'Cause': case 'Cause':
case 'Notes': case 'Notes':
if ( $this->op == 'LIKE' || $this->op == 'NOT LIKE' ) { if ( strstr($this->op, 'LIKE') and ! strstr($this->val, '%' ) ) {
$value = '%'.$value.'%'; $value = '%'.$value.'%';
} }
$value = dbEscape($value); $value = dbEscape($value);
@ -145,7 +147,7 @@ class FilterTerm {
case 'AlarmZoneId': case 'AlarmZoneId':
return ' EXISTS '; return ' EXISTS ';
case 'ExistsInFileSystem': case 'ExistsInFileSystem':
case 'DiskSpace': case 'DiskPercent':
return ''; return '';
} }
@ -202,7 +204,7 @@ class FilterTerm {
switch ( $this->attr ) { switch ( $this->attr ) {
case 'ExistsInFileSystem': case 'ExistsInFileSystem':
case 'DiskSpace': case 'DiskPercent':
$sql .= 'TRUE /*'.$this->attr.'*/'; $sql .= 'TRUE /*'.$this->attr.'*/';
break; break;
case 'MonitorName': case 'MonitorName':
@ -220,49 +222,50 @@ class FilterTerm {
break; break;
# Unspecified start or end, so assume start, this is to support legacy filters # Unspecified start or end, so assume start, this is to support legacy filters
case 'DateTime': case 'DateTime':
$sql .= 'E.StartTime'; $sql .= 'E.StartDateTime';
break; break;
case 'Date': case 'Date':
$sql .= 'to_days(E.StartTime)'; $sql .= 'to_days(E.StartDateTime)';
break; break;
case 'Time': case 'Time':
$sql .= 'extract(hour_second FROM E.StartTime)'; $sql .= 'extract(hour_second FROM E.StartDateTime)';
break; break;
case 'Weekday': case 'Weekday':
$sql .= 'weekday(E.StartTime)'; $sql .= 'weekday(E.StartDateTime)';
break; break;
# Starting Time # Starting Time
case 'StartDateTime': case 'StartDateTime':
$sql .= 'E.StartTime'; $sql .= 'E.StartDateTime';
break; break;
case 'FramesEventId': case 'FramesEventId':
$sql .= 'F.EventId'; $sql .= 'F.EventId';
break; break;
case 'StartDate': case 'StartDate':
$sql .= 'to_days(E.StartTime)'; $sql .= 'to_days(E.StartDateTime)';
break; break;
case 'StartTime': case 'StartTime':
$sql .= 'extract(hour_second FROM E.StartTime)'; $sql .= 'extract(hour_second FROM E.StartDateTime)';
break; break;
case 'StartWeekday': case 'StartWeekday':
$sql .= 'weekday(E.StartTime)'; $sql .= 'weekday(E.StartDateTime)';
break; break;
# Ending Time # Ending Time
case 'EndDateTime': case 'EndDateTime':
$sql .= 'E.EndTime'; $sql .= 'E.EndDateTime';
break; break;
case 'EndDate': case 'EndDate':
$sql .= 'to_days(E.EndTime)'; $sql .= 'to_days(E.EndDateTime)';
break; break;
case 'EndTime': case 'EndTime':
$sql .= 'extract(hour_second FROM E.EndTime)'; $sql .= 'extract(hour_second FROM E.EndDateTime)';
break; break;
case 'EndWeekday': case 'EndWeekday':
$sql .= 'weekday(E.EndTime)'; $sql .= 'weekday(E.EndDateTime)';
break; break;
case 'Emailed':
case 'Id': case 'Id':
case 'Name': case 'Name':
case 'EventDiskSpace': case 'DiskSpace':
case 'MonitorId': case 'MonitorId':
case 'StorageId': case 'StorageId':
case 'SecondaryStorageId': case 'SecondaryStorageId':
@ -400,21 +403,63 @@ class FilterTerm {
} }
public function is_pre_sql() { public function is_pre_sql() {
if ( $this->attr == 'DiskPercent' ) { if ( $this->attr == 'DiskPercent' )
return true;
if ( $this->attr == 'DiskBlocks' )
return true; return true;
}
return false; return false;
} }
public function is_post_sql() { public function is_post_sql() {
if ( $this->attr == 'ExistsInFileSystem' ) { if ( $this->attr == 'ExistsInFileSystem' ) {
return true; return true;
} else if ( $this->attr == 'DiskPercent' ) {
return true;
} }
return false; return false;
} }
public static function is_valid_attr($attr) {
$attrs = array(
'ExistsInFileSystem',
'Emailed',
'DiskSpace',
'DiskPercent',
'DiskBlocks',
'MonitorName',
'ServerId',
'MonitorServerId',
'StorageServerId',
'FilterServerId',
'DateTime',
'Date',
'Time',
'Weekday',
'StartDateTime',
'FramesEventId',
'StartDate',
'StartTime',
'StartWeekday',
'EndDateTime',
'EndDate',
'EndTime',
'EndWeekday',
'Id',
'Name',
'MonitorId',
'StorageId',
'SecondaryStorageId',
'Length',
'Frames',
'AlarmFrames',
'TotScore',
'AvgScore',
'MaxScore',
'Cause',
'Notes',
'StateId',
'Archived'
);
return in_array($attr, $attrs);
}
} # end class FilterTerm } # end class FilterTerm
?> ?>

View File

@ -95,7 +95,7 @@ if ( isset($_REQUEST['object']) and ( $_REQUEST['object'] == 'filter' ) ) {
} else if ( $filter->Background() ) { } else if ( $filter->Background() ) {
$filter->control('start'); $filter->control('start');
} }
$redirect = '?view=filter&Id='.$filter->Id(); $redirect = '?view=filter'.$filter->querystring();
} else if ( $action == 'control' ) { } else if ( $action == 'control' ) {
if ( $_REQUEST['command'] == 'start' if ( $_REQUEST['command'] == 'start'

View File

@ -121,7 +121,8 @@ if ( $action == 'save' ) {
} }
$saferNewName = basename($_REQUEST['newMonitor']['Name']); $saferNewName = basename($_REQUEST['newMonitor']['Name']);
$link_path = $NewStorage->Path().'/'.$saferNewName; $link_path = $NewStorage->Path().'/'.$saferNewName;
if ( !symlink($NewStorage->Path().'/'.$mid, $link_path) ) { // Use a relative path for the target so the link continues to work from backups or directory changes.
if ( !symlink($mid, $link_path) ) {
if ( ! ( file_exists($link_path) and is_link($link_path) ) ) { if ( ! ( file_exists($link_path) and is_link($link_path) ) ) {
ZM\Warning('Unable to symlink ' . $NewStorage->Path().'/'.$mid . ' to ' . $NewStorage->Path().'/'.$saferNewName); ZM\Warning('Unable to symlink ' . $NewStorage->Path().'/'.$mid . ' to ' . $NewStorage->Path().'/'.$saferNewName);
} }

View File

@ -996,26 +996,19 @@ function parseSort($saveToSession=false, $querySep='&amp;') {
$sortColumn = 'E.Cause'; $sortColumn = 'E.Cause';
break; break;
case 'DateTime' : case 'DateTime' :
$sortColumn = 'E.StartTime'; $sortColumn = 'E.StartDateTime';
$_REQUEST['sort_field'] = 'StartTime'; $_REQUEST['sort_field'] = 'StartDateTime';
break; break;
case 'DiskSpace' : case 'DiskSpace' :
$sortColumn = 'E.DiskSpace'; $sortColumn = 'E.DiskSpace';
break; break;
case 'StartTime' : case 'StartTime' :
$sortColumn = 'E.StartTime';
break;
case 'StartDateTime' : case 'StartDateTime' :
// Fix for systems with EVENT_SORT_ORDER set to erroneous StartDateTime. $sortColumn = 'E.StartDateTime';
$_REQUEST['sort_field'] = 'StartTime';
$sortColumn = 'E.StartTime';
break; break;
case 'EndTime' : case 'EndTime' :
$sortColumn = 'E.EndTime';
break;
case 'EndDateTime' : case 'EndDateTime' :
$_REQUEST['sort_field'] = 'EndTime'; $sortColumn = 'E.EndDateTime';
$sortColumn = 'E.EndTime';
break; break;
case 'Length' : case 'Length' :
$sortColumn = 'E.Length'; $sortColumn = 'E.Length';
@ -1051,7 +1044,7 @@ function parseSort($saveToSession=false, $querySep='&amp;') {
$sortColumn = 'F.Score'; $sortColumn = 'F.Score';
break; break;
default: default:
$sortColumn = 'E.StartTime'; $sortColumn = 'E.StartDateTime';
break; break;
} }
if ( !isset($_REQUEST['sort_asc']) ) if ( !isset($_REQUEST['sort_asc']) )

View File

@ -123,7 +123,7 @@ table th:last-child{
a:link { a:link {
color: #3498db; color: #0fbcf9;
text-decoration: none; text-decoration: none;
} }

View File

@ -145,7 +145,7 @@ if ( !$Event->Id() ) {
<span id="dataId" title="<?php echo translate('Id') ?>"><?php echo $Event->Id() ?></span> <span id="dataId" title="<?php echo translate('Id') ?>"><?php echo $Event->Id() ?></span>
<span id="dataMonitor" title="<?php echo translate('Monitor') ?>"><?php echo $Monitor->Id().' '.validHtmlStr($Monitor->Name()) ?></span> <span id="dataMonitor" title="<?php echo translate('Monitor') ?>"><?php echo $Monitor->Id().' '.validHtmlStr($Monitor->Name()) ?></span>
<span id="dataCause" title="<?php echo $Event->Notes()?validHtmlStr($Event->Notes()):translate('AttrCause') ?>"><?php echo validHtmlStr($Event->Cause()) ?></span> <span id="dataCause" title="<?php echo $Event->Notes()?validHtmlStr($Event->Notes()):translate('AttrCause') ?>"><?php echo validHtmlStr($Event->Cause()) ?></span>
<span id="dataTime" title="<?php echo translate('Time') ?>"><?php echo strftime(STRF_FMT_DATETIME_SHORT, strtotime($Event->StartTime())) ?></span> <span id="dataTime" title="<?php echo translate('Time') ?>"><?php echo strftime(STRF_FMT_DATETIME_SHORT, strtotime($Event->StartDateTime())) ?></span>
<span id="dataDuration" title="<?php echo translate('Duration') ?>"><?php echo $Event->Length().'s' ?></span> <span id="dataDuration" title="<?php echo translate('Duration') ?>"><?php echo $Event->Length().'s' ?></span>
<span id="dataFrames" title="<?php echo translate('AttrFrames').'/'.translate('AttrAlarmFrames') ?>"><?php echo $Event->Frames() ?>/<?php echo $Event->AlarmFrames() ?></span> <span id="dataFrames" title="<?php echo translate('AttrFrames').'/'.translate('AttrAlarmFrames') ?>"><?php echo $Event->Frames() ?>/<?php echo $Event->AlarmFrames() ?></span>
<span id="dataScore" title="<?php echo translate('AttrTotalScore').'/'.translate('AttrAvgScore').'/'.translate('AttrMaxScore') ?>"><?php echo $Event->TotScore() ?>/<?php echo $Event->AvgScore() ?>/<?php echo $Event->MaxScore() ?></span> <span id="dataScore" title="<?php echo translate('AttrTotalScore').'/'.translate('AttrAvgScore').'/'.translate('AttrMaxScore') ?>"><?php echo $Event->TotScore() ?>/<?php echo $Event->AvgScore() ?>/<?php echo $Event->MaxScore() ?></span>

View File

@ -104,8 +104,8 @@ getBodyTopHTML();
<th data-sortable="true" data-field="Emailed"><?php echo translate('Emailed') ?></th> <th data-sortable="true" data-field="Emailed"><?php echo translate('Emailed') ?></th>
<th data-sortable="true" data-field="Monitor"><?php echo translate('Monitor') ?></th> <th data-sortable="true" data-field="Monitor"><?php echo translate('Monitor') ?></th>
<th data-sortable="true" data-field="Cause"><?php echo translate('Cause') ?></th> <th data-sortable="true" data-field="Cause"><?php echo translate('Cause') ?></th>
<th data-sortable="true" data-field="StartTime"><?php echo translate('AttrStartTime') ?></th> <th data-sortable="true" data-field="StartDateTime"><?php echo translate('AttrStartTime') ?></th>
<th data-sortable="true" data-field="EndTime"><?php echo translate('AttrEndTime') ?></th> <th data-sortable="true" data-field="EndDateTime"><?php echo translate('AttrEndTime') ?></th>
<th data-sortable="true" data-field="Length"><?php echo translate('Duration') ?></th> <th data-sortable="true" data-field="Length"><?php echo translate('Duration') ?></th>
<th data-sortable="true" data-field="Frames"><?php echo translate('Frames') ?></th> <th data-sortable="true" data-field="Frames"><?php echo translate('Frames') ?></th>
<th data-sortable="true" data-field="AlarmFrames"><?php echo translate('AlarmBrFrames') ?></th> <th data-sortable="true" data-field="AlarmFrames"><?php echo translate('AlarmBrFrames') ?></th>

View File

@ -152,8 +152,8 @@ while ( $event_row = dbFetchNext($results) ) {
<td class="colName"><a href="?view=event&amp;eid=<?php echo $event->Id().$filterQuery.$sortQuery ?>&amp;page=1"><?php echo validHtmlStr($event->Name()).($event->Archived()?'*':'') ?></a></td> <td class="colName"><a href="?view=event&amp;eid=<?php echo $event->Id().$filterQuery.$sortQuery ?>&amp;page=1"><?php echo validHtmlStr($event->Name()).($event->Archived()?'*':'') ?></a></td>
<td class="colMonitorName"><?php echo makeLink( '?view=monitor&amp;mid='.$event->MonitorId(), $event->MonitorName(), canEdit( 'Monitors' ) ) ?></td> <td class="colMonitorName"><?php echo makeLink( '?view=monitor&amp;mid='.$event->MonitorId(), $event->MonitorName(), canEdit( 'Monitors' ) ) ?></td>
<td class="colCause"><?php echo makeLink( '#', validHtmlStr($event->Cause()), canEdit( 'Events' ), 'title="' .htmlspecialchars($event->Notes()). '" class="eDetailLink" data-eid=' .$event->Id(). '"') ?></td> <td class="colCause"><?php echo makeLink( '#', validHtmlStr($event->Cause()), canEdit( 'Events' ), 'title="' .htmlspecialchars($event->Notes()). '" class="eDetailLink" data-eid=' .$event->Id(). '"') ?></td>
<td class="colTime"><?php echo strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->StartTime())) . <td class="colTime"><?php echo strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->StartDateTime())) .
( $event->EndTime() ? ' until ' . strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->EndTime()) ) : '' ) ?> ( $event->EndDateTime() ? ' until ' . strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->EndDateTime()) ) : '' ) ?>
</td> </td>
<td class="colDuration"><?php echo gmdate("H:i:s", $event->Length() ) ?></td> <td class="colDuration"><?php echo gmdate("H:i:s", $event->Length() ) ?></td>
<td class="colFrames"><?php echo makeLink( '?view=frames&amp;eid='.$event->Id(), $event->Frames() ) ?></td> <td class="colFrames"><?php echo makeLink( '?view=frames&amp;eid='.$event->Id(), $event->Frames() ) ?></td>

View File

@ -35,13 +35,12 @@ $filterNames = array(''=>translate('ChooseFilter'));
$filter = NULL; $filter = NULL;
$fid = 0; $fid = 0;
if ( isset($_REQUEST['Id']) ) { if ( isset($_REQUEST['Id']) and $_REQUEST['Id'] ) {
$fid = validInt($_REQUEST['Id']); $fid = validInt($_REQUEST['Id']);
} else if ( isset($_REQUEST['filter[Id]']) ) { } else if ( isset($_REQUEST['filter[Id]']) ) {
$fid = validInt($_REQUEST['filter[Id]']); $fid = validInt($_REQUEST['filter[Id]']);
ZM\Warning("got fid by object id $fid");
} }
$filter = null;
foreach ( ZM\Filter::find(null,array('order'=>'lower(Name)')) as $Filter ) { foreach ( ZM\Filter::find(null,array('order'=>'lower(Name)')) as $Filter ) {
$filterNames[$Filter->Id()] = $Filter->Id() . ' ' . $Filter->Name(); $filterNames[$Filter->Id()] = $Filter->Id() . ' ' . $Filter->Name();
if ( $Filter->Background() ) if ( $Filter->Background() )
@ -53,17 +52,17 @@ foreach ( ZM\Filter::find(null,array('order'=>'lower(Name)')) as $Filter ) {
$filter = $Filter; $filter = $Filter;
} }
} }
if ( !$filter ) { if ( !$filter ) {
$filter = new ZM\Filter(); $filter = new ZM\Filter();
if ( isset($_REQUEST['filter']) ) {
# Update our filter object with whatever changes we have made before saving
$filter->set($_REQUEST['filter']);
}
} else {
ZM\Debug('filter: ' . print_r($filter,true));
} }
if ( isset($_REQUEST['filter']) ) {
# Update our filter object with whatever changes we have made before saving
$filter->set($_REQUEST['filter']);
ZM\Debug("Setting filter from " . print_r($_REQUEST['filter'], true));
}
ZM\Debug('filter: ' . print_r($filter,true));
$conjunctionTypes = ZM\getFilterQueryConjunctionTypes(); $conjunctionTypes = ZM\getFilterQueryConjunctionTypes();
$obracketTypes = array(); $obracketTypes = array();
$cbracketTypes = array(); $cbracketTypes = array();
@ -89,8 +88,8 @@ $attrTypes = array(
'Cause' => translate('AttrCause'), 'Cause' => translate('AttrCause'),
'DiskBlocks' => translate('AttrDiskBlocks'), 'DiskBlocks' => translate('AttrDiskBlocks'),
'DiskPercent' => translate('AttrDiskPercent'), 'DiskPercent' => translate('AttrDiskPercent'),
'DiskSpace' => translate('AttrDiskSpace'), #'StorageDiskSpace' => translate('AttrStorageDiskSpace'),
'EventDiskSpace' => translate('AttrEventDiskSpace'), 'DiskSpace' => translate('AttrEventDiskSpace'),
'EndDateTime' => translate('AttrEndDateTime'), 'EndDateTime' => translate('AttrEndDateTime'),
'EndDate' => translate('AttrEndDate'), 'EndDate' => translate('AttrEndDate'),
'EndTime' => translate('AttrEndTime'), 'EndTime' => translate('AttrEndTime'),

View File

@ -16,7 +16,7 @@ function vjsReplay() {
var overLaid = $j("#videoobj"); var overLaid = $j("#videoobj");
overLaid.append('<p class="vjsMessage" style="height: '+overLaid.height()+'px; line-height: '+overLaid.height()+'px;">No more events</p>'); overLaid.append('<p class="vjsMessage" style="height: '+overLaid.height()+'px; line-height: '+overLaid.height()+'px;">No more events</p>');
} else { } else {
var endTime = (Date.parse(eventData.EndTime)).getTime(); var endTime = (Date.parse(eventData.EndDateTime)).getTime();
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);
@ -584,7 +584,7 @@ function getEventResponse(respObj, respText) {
$('dataCause').setProperty( 'title', causeString ); $('dataCause').setProperty( 'title', causeString );
} }
$('dataCause').set( 'text', eventData.Cause ); $('dataCause').set( 'text', eventData.Cause );
$('dataTime').set( 'text', eventData.StartTime ); $('dataTime').set( 'text', eventData.StartDateTime );
$('dataDuration').set( 'text', eventData.Length ); $('dataDuration').set( 'text', eventData.Length );
$('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 );
@ -606,7 +606,7 @@ function getEventResponse(respObj, respText) {
vid.src({type: 'video/mp4', src: CurEventDefVideoPath}); //Currently mp4 is all we use vid.src({type: 'video/mp4', src: CurEventDefVideoPath}); //Currently mp4 is all we use
console.log('getEventResponse'); console.log('getEventResponse');
initialAlarmCues(eventData.Id);//ajax and render, new event initialAlarmCues(eventData.Id);//ajax and render, new event
addVideoTimingTrack(vid, LabelFormat, eventData.MonitorName, eventData.Length, eventData.StartTime); addVideoTimingTrack(vid, LabelFormat, eventData.MonitorName, eventData.Length, eventData.StartDateTime);
CurEventDefVideoPath = null; CurEventDefVideoPath = null;
$j('#modeValue').html('Replay'); $j('#modeValue').html('Replay');
$j('#zoomValue').html('1'); $j('#zoomValue').html('1');
@ -1088,7 +1088,7 @@ 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 ( $j('#videoobj').length ) { if ( $j('#videoobj').length ) {
vid = videojs('videoobj'); vid = videojs('videoobj');
addVideoTimingTrack(vid, LabelFormat, eventData.MonitorName, eventData.Length, eventData.StartTime); addVideoTimingTrack(vid, LabelFormat, eventData.MonitorName, eventData.Length, eventData.StartDateTime);
$j('.vjs-progress-control').append('<div class="alarmCue"></div>');//add a place for videojs only on first load $j('.vjs-progress-control').append('<div class="alarmCue"></div>');//add a place for videojs only on first load
vid.on('ended', vjsReplay); vid.on('ended', vjsReplay);
vid.on('play', vjsPlay); vid.on('play', vjsPlay);

View File

@ -44,8 +44,8 @@ var eventData = {
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() ?>', StartDateTime: '<?php echo $Event->StartDateTime() ?>',
EndTime: '<?php echo $Event->EndTime() ?>', EndDateTime: '<?php echo $Event->EndDateTime() ?>',
Frames: '<?php echo $Event->Frames() ?>', Frames: '<?php echo $Event->Frames() ?>',
MonitorName: '<?php echo validJsStr($Monitor->Name()) ?>' MonitorName: '<?php echo validJsStr($Monitor->Name()) ?>'
}; };

View File

@ -17,14 +17,14 @@ var params =
"data": "data":
{ {
"search":"some search text", "search":"some search text",
"sort":"StartTime", "sort":"StartDateTime",
"order":"asc", "order":"asc",
"offset":0, "offset":0,
"limit":25 "limit":25
"filter": "filter":
{ {
"Name":"some advanced search text" "Name":"some advanced search text"
"StartTime":"some more advanced search text" "StartDateTime":"some more advanced search text"
} }
}, },
"cache":true, "cache":true,
@ -68,7 +68,7 @@ function processRows(rows) {
row.Frames = '<a href="?view=frames&amp;eid=' + eid + '">' + row.Frames + '</a>'; row.Frames = '<a href="?view=frames&amp;eid=' + eid + '">' + row.Frames + '</a>';
row.AlarmFrames = '<a href="?view=frames&amp;eid=' + eid + '">' + row.AlarmFrames + '</a>'; row.AlarmFrames = '<a href="?view=frames&amp;eid=' + eid + '">' + row.AlarmFrames + '</a>';
row.MaxScore = '<a href="?view=frame&amp;eid=' + eid + '&amp;fid=0">' + row.MaxScore + '</a>'; row.MaxScore = '<a href="?view=frame&amp;eid=' + eid + '&amp;fid=0">' + row.MaxScore + '</a>';
row.Thumbnail = '<a href="?view=event&amp;eid=' + eid + filterQuery + sortQuery + '&amp;page=1">' + row.imgHtml + '</a>'; if ( WEB_LIST_THUMBS ) row.Thumbnail = '<a href="?view=event&amp;eid=' + eid + filterQuery + sortQuery + '&amp;page=1">' + row.imgHtml + '</a>';
}); });
return rows; return rows;
@ -161,6 +161,9 @@ function getEventDetailModal(eid) {
} }
function initPage() { function initPage() {
// Remove the thumbnail column from the DOM if thumbnails are off globally
if ( !WEB_LIST_THUMBS ) $j('th[data-field="Thumbnail"]').remove();
// Load the delete confirmation modal into the DOM // Load the delete confirmation modal into the DOM
getDelConfirmModal(); getDelConfirmModal();

View File

@ -11,3 +11,4 @@ var archivedString = "<?php echo translate('Archived') ?>";
var emailedString = "<?php echo translate('Emailed') ?>"; var emailedString = "<?php echo translate('Emailed') ?>";
var yesString = "<?php echo translate('Yes') ?>"; var yesString = "<?php echo translate('Yes') ?>";
var noString = "<?php echo translate('No') ?>"; var noString = "<?php echo translate('No') ?>";
var WEB_LIST_THUMBS = <?php echo ZM_WEB_LIST_THUMBS?'true':'false' ?>;

View File

@ -76,7 +76,7 @@ if ( !$liveMode ) {
if ( !isset($event['FramesById']) ) { if ( !isset($event['FramesById']) ) {
// Please note that this is the last frame as we sort DESC // Please note that this is the last frame as we sort DESC
$event['FramesById'] = array(); $event['FramesById'] = array();
$frame['NextTimeStampSecs'] = $event['EndTime']; $frame['NextTimeStampSecs'] = $event['EndTimeSecs'];
} else { } else {
$frame['NextTimeStampSecs'] = $next_frames[$frame['EventId']]['TimeStampSecs']; $frame['NextTimeStampSecs'] = $next_frames[$frame['EventId']]['TimeStampSecs'];
$frame['NextFrameId'] = $next_frames[$frame['EventId']]['Id']; $frame['NextFrameId'] = $next_frames[$frame['EventId']]['Id'];

View File

@ -24,7 +24,7 @@ function createEventHtml(zm_event, frame) {
new Element('p').inject(eventHtml).set('text', monitors[zm_event.MonitorId].Name); new Element('p').inject(eventHtml).set('text', monitors[zm_event.MonitorId].Name);
new Element('p').inject(eventHtml).set('text', zm_event.Name+(frame?('('+frame.FrameId+')'):'')); new Element('p').inject(eventHtml).set('text', zm_event.Name+(frame?('('+frame.FrameId+')'):''));
new Element('p').inject(eventHtml).set('text', zm_event.StartTime+' - '+zm_event.Length+'s'); new Element('p').inject(eventHtml).set('text', zm_event.StartDateTime+' - '+zm_event.Length+'s');
new Element('p').inject(eventHtml).set('text', zm_event.Cause); new Element('p').inject(eventHtml).set('text', zm_event.Cause);
if ( zm_event.Notes ) { if ( zm_event.Notes ) {
new Element('p').inject(eventHtml).set('text', zm_event.Notes); new Element('p').inject(eventHtml).set('text', zm_event.Notes);
@ -90,7 +90,7 @@ function showEventData(eventId, frameId) {
showEventDetail( zm_event['frames'][frameId]['html'] ); showEventDetail( zm_event['frames'][frameId]['html'] );
var imagePath = 'index.php?view=image&eid='+eventId+'&fid='+frameId; var imagePath = 'index.php?view=image&eid='+eventId+'&fid='+frameId;
var videoName = zm_event.DefaultVideo; var videoName = zm_event.DefaultVideo;
loadEventImage( imagePath, eventId, frameId, zm_event.Width, zm_event.Height, zm_event.Frames/zm_event.Length, videoName, zm_event.Length, zm_event.StartTime, monitors[zm_event.MonitorId]); loadEventImage( imagePath, eventId, frameId, zm_event.Width, zm_event.Height, zm_event.Frames/zm_event.Length, videoName, zm_event.Length, zm_event.StartDateTime, monitors[zm_event.MonitorId]);
return; return;
} else { } else {
console.log('No frames for ' + frameId); console.log('No frames for ' + frameId);

View File

@ -603,7 +603,7 @@ function getEventCmdResponse( respObj, respText ) {
link.set('text', zm_event.Name); link.set('text', zm_event.Name);
link.inject(row.getElement('td.colName')); link.inject(row.getElement('td.colName'));
row.getElement('td.colTime').set('text', zm_event.StartTime); row.getElement('td.colTime').set('text', zm_event.StartDateTime);
row.getElement('td.colSecs').set('text', zm_event.Length); row.getElement('td.colSecs').set('text', zm_event.Length);
link = new Element('a', {'href': '#', 'events': {'click': openFrames.pass( [zm_event.Id] )}}); link = new Element('a', {'href': '#', 'events': {'click': openFrames.pass( [zm_event.Id] )}});
@ -946,7 +946,8 @@ function initPage() {
}); });
// Only enable the settings button for local cameras // Only enable the settings button for local cameras
settingsBtn.prop('disabled', !(monitorType == 'Local' && canViewControl)); settingsBtn.prop('disabled', !canViewControl);
if ( monitorType != 'Local' ) settingsBtn.hide();
} // initPage } // initPage
// Kick everything off // Kick everything off

View File

@ -114,19 +114,19 @@ if ( count($filter) ) {
$eventsSql = 'SELECT $eventsSql = 'SELECT
E.Id,E.Name,E.StorageId, E.Id,E.Name,E.StorageId,
E.StartTime AS StartTime,UNIX_TIMESTAMP(E.StartTime) AS StartTimeSecs, E.StartDateTime AS StartDateTime,UNIX_TIMESTAMP(E.StartDateTime) AS StartTimeSecs,
CASE WHEN E.EndTime IS NULL THEN (SELECT NOW()) ELSE E.EndTime END AS EndTime, CASE WHEN E.EndDateTime IS NULL THEN (SELECT NOW()) ELSE E.EndDateTime END AS EndDateTime,
UNIX_TIMESTAMP(EndTime) AS EndTimeSecs, UNIX_TIMESTAMP(EndDateTime) AS EndTimeSecs,
E.Length, E.Frames, E.MaxScore,E.Cause,E.Notes,E.Archived,E.MonitorId E.Length, E.Frames, E.MaxScore,E.Cause,E.Notes,E.Archived,E.MonitorId
FROM Events AS E FROM Events AS E
WHERE 1 > 0 WHERE 1 > 0
'; ';
// select E.Id,E.Name,UNIX_TIMESTAMP(E.StartTime) as StartTimeSecs,UNIX_TIMESTAMP(max(DATE_ADD(E.StartTime, Interval Delta+0.5 Second))) as CalcEndTimeSecs, E.Length,max(F.FrameId) as Frames,E.MaxScore,E.Cause,E.Notes,E.Archived,E.MonitorId // select E.Id,E.Name,UNIX_TIMESTAMP(E.StartDateTime) as StartTimeSecs,UNIX_TIMESTAMP(max(DATE_ADD(E.StartDateTime, Interval Delta+0.5 Second))) as CalcEndTimeSecs, E.Length,max(F.FrameId) as Frames,E.MaxScore,E.Cause,E.Notes,E.Archived,E.MonitorId
// from Events as E // from Events as E
// inner join Monitors as M on (E.MonitorId = M.Id) // inner join Monitors as M on (E.MonitorId = M.Id)
// inner join Frames F on F.EventId=E.Id // inner join Frames F on F.EventId=E.Id
// where not isnull(E.Frames) and not isnull(StartTime) "; // where not isnull(E.Frames) and not isnull(StartDateTime) ";
// Note that the delta value seems more accurate than the time stamp for some reason. // Note that the delta value seems more accurate than the time stamp for some reason.
$framesSql = ' $framesSql = '
@ -219,14 +219,14 @@ $initialDisplayInterval = 1000;
if ( isset($_REQUEST['displayinterval']) ) if ( isset($_REQUEST['displayinterval']) )
$initialDisplayInterval = validHtmlStr($_REQUEST['displayinterval']); $initialDisplayInterval = validHtmlStr($_REQUEST['displayinterval']);
#$eventsSql .= ' GROUP BY E.Id,E.Name,E.StartTime,E.Length,E.Frames,E.MaxScore,E.Cause,E.Notes,E.Archived,E.MonitorId'; #$eventsSql .= ' GROUP BY E.Id,E.Name,E.StartDateTime,E.Length,E.Frames,E.MaxScore,E.Cause,E.Notes,E.Archived,E.MonitorId';
$minTimeSecs = $maxTimeSecs = 0; $minTimeSecs = $maxTimeSecs = 0;
if ( isset($minTime) && isset($maxTime) ) { if ( isset($minTime) && isset($maxTime) ) {
$minTimeSecs = strtotime($minTime); $minTimeSecs = strtotime($minTime);
$maxTimeSecs = strtotime($maxTime); $maxTimeSecs = strtotime($maxTime);
$eventsSql .= " AND EndTime > '" . $minTime . "' AND StartTime < '" . $maxTime . "'"; $eventsSql .= " AND EndDateTime > '" . $minTime . "' AND StartDateTime < '" . $maxTime . "'";
$framesSql .= " AND EndTime > '" . $minTime . "' AND StartTime < '" . $maxTime . "'"; $framesSql .= " AND EndDateTime > '" . $minTime . "' AND StartDateTime < '" . $maxTime . "'";
$framesSql .= ") AND TimeStamp > '" . $minTime . "' AND TimeStamp < '" . $maxTime . "'"; $framesSql .= ") AND TimeStamp > '" . $minTime . "' AND TimeStamp < '" . $maxTime . "'";
} else { } else {
$framesSql .= ')'; $framesSql .= ')';

View File

@ -231,6 +231,7 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*', GLOB_ONLYDIR)) as
<td class="colUrl"><?php echo makeLink('#', validHtmlStr($Server->Url()), $canEdit, $svr_opt ) ?></td> <td class="colUrl"><?php echo makeLink('#', validHtmlStr($Server->Url()), $canEdit, $svr_opt ) ?></td>
<td class="colPathToIndex"><?php echo makeLink('#', validHtmlStr($Server->PathToIndex()), $canEdit, $svr_opt ) ?></td> <td class="colPathToIndex"><?php echo makeLink('#', validHtmlStr($Server->PathToIndex()), $canEdit, $svr_opt ) ?></td>
<td class="colPathToZMS"><?php echo makeLink('#', validHtmlStr($Server->PathToZMS()), $canEdit, $svr_opt ) ?></td> <td class="colPathToZMS"><?php echo makeLink('#', validHtmlStr($Server->PathToZMS()), $canEdit, $svr_opt ) ?></td>
<td class="colPathToAPI"><?php echo makeLink('#', validHtmlStr($Server->PathToAPI()), $canEdit, $svr_opt ) ?></td>
<td class="colStatus <?php if ( $Server->Status() == 'NotRunning' ) { echo 'danger'; } ?>"> <td class="colStatus <?php if ( $Server->Status() == 'NotRunning' ) { echo 'danger'; } ?>">
<?php echo makeLink('#', validHtmlStr($Server->Status()), $canEdit, $svr_opt) ?></td> <?php echo makeLink('#', validHtmlStr($Server->Status()), $canEdit, $svr_opt) ?></td>
<td class="colMonitorCount"><?php echo makeLink('#', validHtmlStr($monitor_counts[$Server->Id()]), $canEdit, $svr_opt) ?></td> <td class="colMonitorCount"><?php echo makeLink('#', validHtmlStr($monitor_counts[$Server->Id()]), $canEdit, $svr_opt) ?></td>

View File

@ -65,8 +65,8 @@ $filterQuery = $filter['query'];
ZM\Debug($filterQuery); ZM\Debug($filterQuery);
$eventsSql = 'SELECT *, $eventsSql = 'SELECT *,
UNIX_TIMESTAMP(E.StartTime) AS StartTimeSecs, UNIX_TIMESTAMP(E.StartDateTime) AS StartTimeSecs,
UNIX_TIMESTAMP(EndTime) AS EndTimeSecs UNIX_TIMESTAMP(EndDateTime) AS EndTimeSecs
FROM Events AS E FROM Events AS E
WHERE 1 > 0 WHERE 1 > 0
'; ';
@ -77,7 +77,7 @@ if ( count($selected_monitor_ids) ) {
$eventsSql .= ' AND MonitorId IN ('.implode(',', $selected_monitor_ids).')'; $eventsSql .= ' AND MonitorId IN ('.implode(',', $selected_monitor_ids).')';
} }
if ( isset($minTime) && isset($maxTime) ) { if ( isset($minTime) && isset($maxTime) ) {
$eventsSql .= " AND EndTime > '" . $minTime . "' AND StartTime < '" . $maxTime . "'"; $eventsSql .= " AND EndDateTime > '" . $minTime . "' AND StartDateTime < '" . $maxTime . "'";
} }
$eventsSql .= ' ORDER BY Id ASC'; $eventsSql .= ' ORDER BY Id ASC';
@ -211,8 +211,8 @@ for ( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
</div></td> </div></td>
<td class="colServer"><?php echo validHtmlStr($Monitor->Server()->Name())?></td> <td class="colServer"><?php echo validHtmlStr($Monitor->Server()->Name())?></td>
<td class="colEvents"><a href="?view=<?php echo ZM_WEB_EVENTS_VIEW ?>&amp;page=1<?php echo $monitor_filter['query'] ?>"><?php echo isset($EventsByMonitor[$Monitor->Id()])?count($EventsByMonitor[$Monitor->Id()]['Events']):0 ?></a></td> <td class="colEvents"><a href="?view=<?php echo ZM_WEB_EVENTS_VIEW ?>&amp;page=1<?php echo $monitor_filter['query'] ?>"><?php echo isset($EventsByMonitor[$Monitor->Id()])?count($EventsByMonitor[$Monitor->Id()]['Events']):0 ?></a></td>
<td class="colFirstEvent"><?php echo $FirstEvent ? $FirstEvent->link_to($FirstEvent->Id().' at '.$FirstEvent->StartTime()) : 'none'?></td> <td class="colFirstEvent"><?php echo $FirstEvent ? $FirstEvent->link_to($FirstEvent->Id().' at '.$FirstEvent->StartDateTime()) : 'none'?></td>
<td class="colLastEvent"><?php echo $LastEvent ? $LastEvent->link_to($LastEvent->Id().' at '.$LastEvent->StartTime()) : 'none'?></td> <td class="colLastEvent"><?php echo $LastEvent ? $LastEvent->link_to($LastEvent->Id().' at '.$LastEvent->StartDateTime()) : 'none'?></td>
<td class="colMinGap"><?php echo $MinGap ?></td> <td class="colMinGap"><?php echo $MinGap ?></td>
<td class="colMaxGap"><?php echo $MaxGap ?></td> <td class="colMaxGap"><?php echo $MaxGap ?></td>
<td class="colFileMissing<?php echo count($FileMissing) ? ' errorText' : ''?>"> <td class="colFileMissing<?php echo count($FileMissing) ? ' errorText' : ''?>">

View File

@ -128,9 +128,9 @@ $chart = array(
$monitors = array(); $monitors = array();
# The as E, and joining with Monitors is required for the filterSQL filters. # The as E, and joining with Monitors is required for the filterSQL filters.
$rangeSql = 'SELECT min(E.StartTime) AS MinTime, max(E.EndTime) AS MaxTime FROM Events AS E INNER JOIN Monitors AS M ON (E.MonitorId = M.Id) WHERE NOT isnull(E.StartTime) AND NOT isnull(E.EndTime)'; $rangeSql = 'SELECT min(E.StartDateTime) AS MinTime, max(E.EndDateTime) AS MaxTime FROM Events AS E INNER JOIN Monitors AS M ON (E.MonitorId = M.Id) WHERE NOT isnull(E.StartDateTime) AND NOT isnull(E.EndDateTime)';
$eventsSql = 'SELECT E.* FROM Events AS E INNER JOIN Monitors AS M ON (E.MonitorId = M.Id) WHERE NOT isnull(StartTime)'; $eventsSql = 'SELECT E.* FROM Events AS E INNER JOIN Monitors AS M ON (E.MonitorId = M.Id) WHERE NOT isnull(StartDateTime)';
$eventIdsSql = 'SELECT E.Id FROM Events AS E INNER JOIN Monitors AS M ON (E.MonitorId = M.Id) WHERE NOT isnull(StartTime)'; $eventIdsSql = 'SELECT E.Id FROM Events AS E INNER JOIN Monitors AS M ON (E.MonitorId = M.Id) WHERE NOT isnull(StartDateTime)';
$eventsValues = array(); $eventsValues = array();
if ( !empty($user['MonitorIds']) ) { if ( !empty($user['MonitorIds']) ) {
@ -277,8 +277,8 @@ $midTimeT = $minTimeT + $halfRange;
$midTime = strftime(STRF_FMT_DATETIME_DB, $midTimeT); $midTime = strftime(STRF_FMT_DATETIME_DB, $midTimeT);
if ( isset($minTime) && isset($maxTime) ) { if ( isset($minTime) && isset($maxTime) ) {
$eventsSql .= " AND EndTime >= '$minTime' AND StartTime <= '$maxTime'"; $eventsSql .= " AND EndDateTime >= '$minTime' AND StartDateTime <= '$maxTime'";
$eventIdsSql .= " AND EndTime >= '$minTime' AND StartTime <= '$maxTime'"; $eventIdsSql .= " AND EndDateTime >= '$minTime' AND StartDateTime <= '$maxTime'";
} }
if ( 0 ) { if ( 0 ) {
@ -332,13 +332,13 @@ while( $event = $events_result->fetch(PDO::FETCH_ASSOC) ) {
$currEventSlots = &$monEventSlots[$event['MonitorId']]; $currEventSlots = &$monEventSlots[$event['MonitorId']];
$currFrameSlots = &$monFrameSlots[$event['MonitorId']]; $currFrameSlots = &$monFrameSlots[$event['MonitorId']];
$startTimeT = strtotime($event['StartTime']); $startTimeT = strtotime($event['StartDateTime']);
$startIndex = $rawStartIndex = (int)(($startTimeT - $chart['data']['x']['lo']) / $chart['data']['x']['density']); $startIndex = $rawStartIndex = (int)(($startTimeT - $chart['data']['x']['lo']) / $chart['data']['x']['density']);
if ( $startIndex < 0 ) if ( $startIndex < 0 )
$startIndex = 0; $startIndex = 0;
if ( isset($event['EndTime']) ) if ( isset($event['EndDateTime']) )
$endTimeT = strtotime($event['EndTime']); $endTimeT = strtotime($event['EndDateTime']);
else else
$endTimeT = time(); $endTimeT = time();
$endIndex = $rawEndIndex = (int)(($endTimeT - $chart['data']['x']['lo']) / $chart['data']['x']['density']); $endIndex = $rawEndIndex = (int)(($endTimeT - $chart['data']['x']['lo']) / $chart['data']['x']['density']);