This commit is contained in:
Isaac Connor 2018-01-25 08:42:08 -08:00
commit 356015a492
46 changed files with 901 additions and 509 deletions

View File

@ -608,9 +608,6 @@ CREATE TABLE `Monitors` (
`WebColour` varchar(32) NOT NULL default 'red', `WebColour` varchar(32) NOT NULL default 'red',
`Exif` tinyint(1) unsigned NOT NULL default '0', `Exif` tinyint(1) unsigned NOT NULL default '0',
`Sequence` smallint(5) unsigned default NULL, `Sequence` smallint(5) unsigned default NULL,
`Status` enum('Unknown','NotRunning','Running','NoSignal','Signal') NOT NULL default 'Unknown',
`CaptureFPS` DECIMAL(10,2) NOT NULL default 0,
`AnalysisFPS` DECIMAL(5,2) NOT NULL default 0,
`TotalEvents` int(10) unsigned, `TotalEvents` int(10) unsigned,
`TotalEventDiskSpace` bigint unsigned, `TotalEventDiskSpace` bigint unsigned,
`HourEvents` int(10) unsigned, `HourEvents` int(10) unsigned,
@ -629,6 +626,14 @@ CREATE TABLE `Monitors` (
CREATE INDEX `Monitors_ServerId_idx` ON `Monitors` (`ServerId`); CREATE INDEX `Monitors_ServerId_idx` ON `Monitors` (`ServerId`);
DROP TABLE IF EXISTS `Monitor_Status`;
CREATE TABLE `Monitor_Status` (
`Id` int(10) unsigned NOT NULL,
`Status` enum('Unknown','NotRunning','Running','NoSignal','Signal') NOT NULL default 'Unknown',
`CaptureFPS` DECIMAL(10,2) NOT NULL default 0,
`AnalysisFPS` DECIMAL(5,2) NOT NULL default 0,
PRIMARY KEY (`Id`)
) ENGINE=MEMORY;
-- --
-- Table structure for table `States` -- Table structure for table `States`
-- PP - Added IsActive to track custom run states -- PP - Added IsActive to track custom run states

View File

@ -1,7 +1,7 @@
-- --
-- This updates a 1.29.0 database to 1.30.0 -- This updates a 1.29.0 database to 1.30.0
-- --
SELECT 'Checking for SaveJPEGs in Monitors';
SET @s = (SELECT IF( SET @s = (SELECT IF(
(SELECT COUNT(*) (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS FROM INFORMATION_SCHEMA.COLUMNS
@ -16,6 +16,7 @@ SET @s = (SELECT IF(
PREPARE stmt FROM @s; PREPARE stmt FROM @s;
EXECUTE stmt; EXECUTE stmt;
SELECT 'Checking for VideoWriter in Monitors';
SET @s = (SELECT IF( SET @s = (SELECT IF(
(SELECT COUNT(*) (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS FROM INFORMATION_SCHEMA.COLUMNS
@ -30,6 +31,7 @@ SET @s = (SELECT IF(
PREPARE stmt FROM @s; PREPARE stmt FROM @s;
EXECUTE stmt; EXECUTE stmt;
SELECT 'Checking for EncoderParameters in Monitors';
SET @s = (SELECT IF( SET @s = (SELECT IF(
(SELECT COUNT(*) (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS FROM INFORMATION_SCHEMA.COLUMNS
@ -44,6 +46,7 @@ SET @s = (SELECT IF(
PREPARE stmt FROM @s; PREPARE stmt FROM @s;
EXECUTE stmt; EXECUTE stmt;
SELECT 'Checking for DefaultVideo in Events';
SET @s = (SELECT IF( SET @s = (SELECT IF(
(SELECT COUNT(*) (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS FROM INFORMATION_SCHEMA.COLUMNS
@ -58,6 +61,7 @@ SET @s = (SELECT IF(
PREPARE stmt FROM @s; PREPARE stmt FROM @s;
EXECUTE stmt; EXECUTE stmt;
SELECT 'Checking for RecordAudio in Monitors';
SET @s = (SELECT IF( SET @s = (SELECT IF(
(SELECT COUNT(*) (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS FROM INFORMATION_SCHEMA.COLUMNS

View File

@ -3,6 +3,7 @@
-- --
-- Add StateId Column to Events. -- Add StateId Column to Events.
-- --
SELECT 'Checkfor StateId IN Events';
SET @s = (SELECT IF( SET @s = (SELECT IF(
(SELECT COUNT(*) (SELECT COUNT(*)

View File

@ -2,6 +2,7 @@
-- Update Filters table to have a Concurrent Column -- Update Filters table to have a Concurrent Column
-- --
SELECT 'Checking for Concurrent in Filters';
SET @s = (SELECT IF( SET @s = (SELECT IF(
(SELECT COUNT(*) (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS FROM INFORMATION_SCHEMA.COLUMNS

View File

@ -2,7 +2,11 @@ SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Servers' AND table_name = 'Servers'
AND column_name = 'zmstats.pl' AND column_name = 'zmstats.pl'
) > 0, ) > 0 AND ( SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Servers'
AND column_name = 'zmstats'
) = 0
,
"ALTER TABLE Servers CHANGE COLUMN `zmstats.pl` `zmstats` BOOLEAN NOT NULL DEFAULT FALSE", "ALTER TABLE Servers CHANGE COLUMN `zmstats.pl` `zmstats` BOOLEAN NOT NULL DEFAULT FALSE",
"SELECT 'zmstats.pl has already been changed to zmstats'" "SELECT 'zmstats.pl has already been changed to zmstats'"
)); ));
@ -13,8 +17,27 @@ EXECUTE stmt;
SET @s = (SELECT IF( SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Servers' AND table_name = 'Servers'
AND column_name = 'zmaudit.pl' AND column_name = 'zmstats.pl'
) > 0, ) > 0,
"ALTER TABLE Servers DROP COLUMN `zmstats.pl`",
"SELECT 'zmstats.pl has already been removed'"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Servers'
AND column_name = 'zmaudit.pl'
) > 0
AND
( SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Servers'
AND column_name = 'zmaudit'
) = 0
,
"ALTER TABLE Servers CHANGE COLUMN `zmaudit.pl` `zmaudit` BOOLEAN NOT NULL DEFAULT FALSE", "ALTER TABLE Servers CHANGE COLUMN `zmaudit.pl` `zmaudit` BOOLEAN NOT NULL DEFAULT FALSE",
"SELECT 'zmaudit.pl has already been changed to zmaudit'" "SELECT 'zmaudit.pl has already been changed to zmaudit'"
)); ));
@ -25,11 +48,41 @@ EXECUTE stmt;
SET @s = (SELECT IF( SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Servers' AND table_name = 'Servers'
AND column_name = 'zmtrigger.pl' AND column_name = 'zmaudit.pl'
) > 0, ) > 0,
"ALTER TABLE Servers DROP COLUMN `zmaudit.pl`",
"SELECT 'zmaudit.pl has already been removed'"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Servers'
AND column_name = 'zmtrigger.pl'
) > 0
AND
( SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Servers'
AND column_name = 'zmtrigger'
) = 0
,
"ALTER TABLE Servers CHANGE COLUMN `zmtrigger.pl` `zmtrigger` BOOLEAN NOT NULL DEFAULT FALSE", "ALTER TABLE Servers CHANGE COLUMN `zmtrigger.pl` `zmtrigger` BOOLEAN NOT NULL DEFAULT FALSE",
"SELECT 'zmtrigger.pl has already been changed to zmtrigger'" "SELECT 'zmtrigger.pl has already been changed to zmtrigger'"
)); ));
PREPARE stmt FROM @s; PREPARE stmt FROM @s;
EXECUTE stmt; EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Servers'
AND column_name = 'zmtrigger.pl'
) > 0,
"ALTER TABLE Servers DROP COLUMN `zmtrigger.pl`",
"SELECT 'zmtrigger.pl has already been removed'"
));
PREPARE stmt FROM @s;
EXECUTE stmt;

100
db/zm_update-1.31.27.sql Normal file
View File

@ -0,0 +1,100 @@
delimiter //
DROP TRIGGER IF EXISTS event_update_trigger;
CREATE TRIGGER event_update_trigger AFTER UPDATE ON Events
FOR EACH ROW
BEGIN
declare diff BIGINT default 0;
set diff = NEW.DiskSpace - OLD.DiskSpace;
IF ( NEW.StorageId = OLD.StorageID ) THEN
IF ( diff ) THEN
call update_storage_stats(OLD.StorageId, diff);
END IF;
ELSE
IF ( NEW.DiskSpace ) THEN
call update_storage_stats(NEW.StorageId, NEW.DiskSpace);
END IF;
IF ( OLD.DiskSpace ) THEN
call update_storage_stats(OLD.StorageId, -OLD.DiskSpace);
END IF;
END IF;
UPDATE Events_Hour SET DiskSpace=NEW.DiskSpace WHERE EventId=NEW.Id;
UPDATE Events_Day SET DiskSpace=NEW.DiskSpace WHERE EventId=NEW.Id;
UPDATE Events_Week SET DiskSpace=NEW.DiskSpace WHERE EventId=NEW.Id;
UPDATE Events_Month SET DiskSpace=NEW.DiskSpace WHERE EventId=NEW.Id;
IF ( NEW.Archived != OLD.Archived ) THEN
IF ( NEW.Archived ) THEN
INSERT INTO Events_Archived (EventId,MonitorId,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.DiskSpace);
UPDATE Monitors SET ArchivedEvents = COALESCE(ArchivedEvents,0)+1, ArchivedEventDiskSpace = COALESCE(ArchivedEventDiskSpace,0) + COALESCE(NEW.DiskSpace,0) WHERE Id=NEW.MonitorId;
ELSEIF ( OLD.Archived ) THEN
DELETE FROM Events_Archived WHERE EventId=OLD.Id;
UPDATE Monitors SET ArchivedEvents = COALESCE(ArchivedEvents,0)-1, ArchivedEventDiskSpace = COALESCE(ArchivedEventDiskSpace,0) - COALESCE(OLD.DiskSpace,0) WHERE Id=OLD.MonitorId;
ELSE
IF ( OLD.DiskSpace != NEW.DiskSpace ) THEN
UPDATE Events_Archived SET DiskSpace=NEW.DiskSpace WHERE EventId=NEW.Id;
UPDATE Monitors SET
ArchivedEventDiskSpace = COALESCE(ArchivedEventDiskSpace,0) - COALESCE(OLD.DiskSpace,0) + COALESCE(NEW.DiskSpace,0)
WHERE Id=OLD.MonitorId;
END IF;
END IF;
END IF;
IF (
( (OLD.DiskSpace IS NOT NULL) AND (NEW.DiskSpace IS NULL) )
OR
( (OLD.DiskSpace IS NULL) AND (NEW.DiskSpace IS NOT NULL) )
OR ( OLD.DiskSpace != NEW.DiskSpace )
) THEN
UPDATE Monitors SET TotalEventDiskSpace = COALESCE(TotalEventDiskSpace,0) - COALESCE(OLD.DiskSpace,0) + COALESCE(NEW.DiskSpace,0) WHERE Id=OLD.MonitorId;
END IF;
END;
//
DROP TRIGGER IF EXISTS event_insert_trigger;
create trigger event_insert_trigger after insert on Events
for each row
begin
INSERT INTO Events_Hour (EventId,MonitorId,StartTime,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.StartTime,0);
INSERT INTO Events_Day (EventId,MonitorId,StartTime,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.StartTime,0);
INSERT INTO Events_Week (EventId,MonitorId,StartTime,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.StartTime,0);
INSERT INTO Events_Month (EventId,MonitorId,StartTime,DiskSpace) VALUES (NEW.Id,NEW.MonitorId,NEW.StartTime,0);
UPDATE Monitors SET TotalEvents = COALESCE(TotalEvents,0)+1 WHERE Id=NEW.MonitorId;
end;
//
UPDATE Monitors INNER JOIN (
SELECT MonitorId,
COUNT(Id) AS TotalEvents,
SUM(DiskSpace) AS TotalEventDiskSpace,
SUM(IF(Archived,1,0)) AS ArchivedEvents,
SUM(IF(Archived,DiskSpace,0)) AS ArchivedEventDiskSpace,
SUM(IF(StartTime > DATE_SUB(NOW(), INTERVAL 1 hour),1,0)) AS HourEvents,
SUM(IF(StartTime > DATE_SUB(NOW(), INTERVAL 1 hour),DiskSpace,0)) AS HourEventDiskSpace,
SUM(IF(StartTime > DATE_SUB(NOW(), INTERVAL 1 day),1,0)) AS DayEvents,
SUM(IF(StartTime > DATE_SUB(NOW(), INTERVAL 1 day),DiskSpace,0)) AS DayEventDiskSpace,
SUM(IF(StartTime > DATE_SUB(NOW(), INTERVAL 1 week),1,0)) AS WeekEvents,
SUM(IF(StartTime > DATE_SUB(NOW(), INTERVAL 1 week),DiskSpace,0)) AS WeekEventDiskSpace,
SUM(IF(StartTime > DATE_SUB(NOW(), INTERVAL 1 month),1,0)) AS MonthEvents,
SUM(IF(StartTime > DATE_SUB(NOW(), INTERVAL 1 month),DiskSpace,0)) AS MonthEventDiskSpace
FROM Events GROUP BY MonitorId
) AS E ON E.MonitorId=Monitors.Id SET
Monitors.TotalEvents = E.TotalEvents,
Monitors.TotalEventDiskSpace = E.TotalEventDiskSpace,
Monitors.ArchivedEvents = E.ArchivedEvents,
Monitors.ArchivedEventDiskSpace = E.ArchivedEventDiskSpace,
Monitors.HourEvents = E.HourEvents,
Monitors.HourEventDiskSpace = E.HourEventDiskSpace,
Monitors.DayEvents = E.DayEvents,
Monitors.DayEventDiskSpace = E.DayEventDiskSpace,
Monitors.WeekEvents = E.WeekEvents,
Monitors.WeekEventDiskSpace = E.WeekEventDiskSpace,
Monitors.MonthEvents = E.MonthEvents,
Monitors.MonthEventDiskSpace = E.MonthEventDiskSpace//

57
db/zm_update-1.31.28.sql Normal file
View File

@ -0,0 +1,57 @@
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Monitor_Status'
) > 0
,
"SELECT 'Monitor_Status Already exists'",
"
CREATE TABLE `Monitor_Status` (
`Id` int(10) unsigned NOT NULL,
`Status` enum('Unknown','NotRunning','Running','NoSignal','Signal') NOT NULL default 'Unknown',
`CaptureFPS` DECIMAL(10,2) NOT NULL default 0,
`AnalysisFPS` DECIMAL(5,2) NOT NULL default 0,
PRIMARY KEY (`Id`)
) ENGINE=MEMORY"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Monitors'
AND column_name = 'Status'
) > 0
,
"ALTER TABLE Monitors DROP COLUMN Status",
"SELECT 'Monitor Status already removed.'"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Monitors'
AND column_name = 'CaptureFPS'
) > 0
,
"ALTER TABLE Monitors DROP COLUMN CaptureFPS",
"SELECT 'Monitor CaptureFPS already removed.'"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Monitors'
AND column_name = 'AnalysisFPS'
) > 0
,
"ALTER TABLE Monitors DROP COLUMN AnalysisFPS",
"SELECT 'Monitor AnalysisFPS already removed.'"
));
PREPARE stmt FROM @s;
EXECUTE stmt;

View File

@ -2,6 +2,7 @@
-- This adds StorageAreas -- This adds StorageAreas
-- --
SELECT 'Checking For Storage Table';
SET @s = (SELECT IF( SET @s = (SELECT IF(
(SELECT COUNT(*) (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.TABLES FROM INFORMATION_SCHEMA.TABLES
@ -24,6 +25,7 @@ EXECUTE stmt;
-- Add StorageId column to Monitors -- Add StorageId column to Monitors
-- --
SELECT 'Checking For StorageId in Monitors';
SET @s = (SELECT IF( SET @s = (SELECT IF(
(SELECT COUNT(*) (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS FROM INFORMATION_SCHEMA.COLUMNS
@ -42,6 +44,7 @@ EXECUTE stmt;
-- Add StorageId column to Eventss -- Add StorageId column to Eventss
-- --
SELECT 'Checking For StorageId in Events';
SET @s = (SELECT IF( SET @s = (SELECT IF(
(SELECT COUNT(*) (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS FROM INFORMATION_SCHEMA.COLUMNS
@ -56,6 +59,7 @@ SET @s = (SELECT IF(
PREPARE stmt FROM @s; PREPARE stmt FROM @s;
EXECUTE stmt; EXECUTE stmt;
SELECT 'Updating Monitors SETTING StorageId to default';
UPDATE Monitors SET StorageId = 0 WHERE StorageId IS NULL; UPDATE Monitors SET StorageId = 0 WHERE StorageId IS NULL;
ALTER TABLE Monitors MODIFY `StorageId` smallint(5) unsigned NOT NULL default 0; ALTER TABLE Monitors MODIFY `StorageId` smallint(5) unsigned NOT NULL default 0;
UPDATE Events SET StorageId = 0 WHERE StorageId IS NULL; UPDATE Events SET StorageId = 0 WHERE StorageId IS NULL;
@ -78,6 +82,7 @@ EXECUTE stmt;
-- --
-- Update Monitors table to have an Index on ServerId -- Update Monitors table to have an Index on ServerId
-- --
SELECT 'Create Index For ServerId on Monitors';
SET @s = (SELECT IF( SET @s = (SELECT IF(
(SELECT COUNT(*) (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.STATISTICS FROM INFORMATION_SCHEMA.STATISTICS
@ -96,6 +101,7 @@ EXECUTE stmt;
-- --
-- Update Server table to have an Index on Name -- Update Server table to have an Index on Name
-- --
SELECT 'Create Index FOR Name on Servers';
SET @s = (SELECT IF( SET @s = (SELECT IF(
(SELECT COUNT(*) (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.STATISTICS FROM INFORMATION_SCHEMA.STATISTICS
@ -111,15 +117,19 @@ PREPARE stmt FROM @s;
EXECUTE stmt; EXECUTE stmt;
SELECT 'ALTER TABLE Logs MODIFY Message TEXT NOT NULL';
-- ALTER TABLE Logs ALTER Message DROP DEFAULT; -- ALTER TABLE Logs ALTER Message DROP DEFAULT;
ALTER TABLE Logs MODIFY Message TEXT NOT NULL; ALTER TABLE Logs MODIFY Message TEXT NOT NULL;
SELECT 'ALTER TABLE Config MODIFY DefaultValue TEXT';
ALTER TABLE Config MODIFY DefaultValue TEXT; ALTER TABLE Config MODIFY DefaultValue TEXT;
-- --
-- Add an Id column and make it the primary key of the Filters table -- Add an Id column and make it the primary key of the Filters table
-- --
SELECT 'Check for Id column in Filter';
SET @s = (SELECT IF( SET @s = (SELECT IF(
(SELECT COUNT(*) (SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS FROM INFORMATION_SCHEMA.COLUMNS

View File

@ -1 +1,12 @@
ALTER TABLE Groups MODIFY `MonitorIds` text NOT NULL; SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Groups'
AND column_name = 'MonitorIds'
) > 0,
"ALTER TABLE Groups MODIFY `MonitorIds` text NOT NULL",
"SELECT 'Groups no longer has MonitorIds'"
));
PREPARE stmt FROM @s;
EXECUTE stmt;

View File

@ -90,9 +90,10 @@ sub Time {
$_[0]{Time} = $_[1]; $_[0]{Time} = $_[1];
} }
if ( ! defined $_[0]{Time} ) { if ( ! defined $_[0]{Time} ) {
if ( $_[0]{StartTime} ) {
$_[0]{Time} = Date::Parse::str2time( $_[0]{StartTime} ); $_[0]{Time} = Date::Parse::str2time( $_[0]{StartTime} );
} }
}
return $_[0]{Time}; return $_[0]{Time};
} }
@ -115,6 +116,10 @@ sub find {
push @sql_filters , ' Name = ? '; push @sql_filters , ' Name = ? ';
push @sql_values, $sql_filters{Name}; push @sql_values, $sql_filters{Name};
} }
if ( exists $sql_filters{Id} ) {
push @sql_filters , ' Id = ? ';
push @sql_values, $sql_filters{Id};
}
$sql .= ' WHERE ' . join(' AND ', @sql_filters ) if @sql_filters; $sql .= ' WHERE ' . join(' AND ', @sql_filters ) if @sql_filters;
$sql .= ' LIMIT ' . $sql_filters{limit} if $sql_filters{limit}; $sql .= ' LIMIT ' . $sql_filters{limit} if $sql_filters{limit};
@ -230,8 +235,15 @@ sub LinkPath {
), ),
'.'.$$event{Id} '.'.$$event{Id}
); );
} elsif ( $$event{Path} ) {
if ( ( $$event{Path} =~ /^(\d+\/\d{4}\/\d{2}\/\d{2})/ ) ) {
$$event{LinkPath} = $1.'/.'.$$event{Id};
} else { } else {
Error("Event $$event{Id} has no value for Time(), unable to determine link path"); Error("Unable to get LinkPath from Path for $$event{Id} $$event{Path}");
$$event{LinkPath} = '';
}
} else {
Error("Event $$event{Id} $$event{Path} has no value for Time(), unable to determine link path");
$$event{LinkPath} = ''; $$event{LinkPath} = '';
} }
} # end if Scheme } # end if Scheme
@ -243,7 +255,7 @@ sub LinkPath {
sub GenerateVideo { sub GenerateVideo {
my ( $self, $rate, $fps, $scale, $size, $overwrite, $format ) = @_; my ( $self, $rate, $fps, $scale, $size, $overwrite, $format ) = @_;
my $event_path = $self->getPath( ); my $event_path = $self->Path( );
chdir( $event_path ); chdir( $event_path );
( my $video_name = $self->{Name} ) =~ s/\s/_/g; ( my $video_name = $self->{Name} ) =~ s/\s/_/g;
@ -337,13 +349,9 @@ sub delete {
} }
Info( "Deleting event $event->{Id} from Monitor $event->{MonitorId} StartTime:$event->{StartTime}\n" ); Info( "Deleting event $event->{Id} from Monitor $event->{MonitorId} StartTime:$event->{StartTime}\n" );
$ZoneMinder::Database::dbh->ping(); $ZoneMinder::Database::dbh->ping();
# Do it individually to avoid locking up the table for new events
my $sql = 'DELETE FROM Events WHERE Id=?'; $ZoneMinder::Database::dbh->begin_work();
my $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql ) $event->lock_and_load();
or Error( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() );
my $res = $sth->execute( $event->{Id} )
or Error( "Can't execute '$sql': ".$sth->errstr() );
$sth->finish();
if ( ! $Config{ZM_OPT_FAST_DELETE} ) { if ( ! $Config{ZM_OPT_FAST_DELETE} ) {
my $sql = 'DELETE FROM Frames WHERE EventId=?'; my $sql = 'DELETE FROM Frames WHERE EventId=?';
@ -352,6 +360,10 @@ sub delete {
my $res = $sth->execute( $event->{Id} ) my $res = $sth->execute( $event->{Id} )
or Error( "Can't execute '$sql': ".$sth->errstr() ); or Error( "Can't execute '$sql': ".$sth->errstr() );
$sth->finish(); $sth->finish();
if ( $ZoneMinder::Database::dbh->errstr() ) {
$ZoneMinder::Database::dbh->commit();
return;
}
$sql = 'DELETE FROM Stats WHERE EventId=?'; $sql = 'DELETE FROM Stats WHERE EventId=?';
$sth = $ZoneMinder::Database::dbh->prepare_cached( $sql ) $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql )
@ -359,11 +371,23 @@ sub delete {
$res = $sth->execute( $event->{Id} ) $res = $sth->execute( $event->{Id} )
or Error( "Can't execute '$sql': ".$sth->errstr() ); or Error( "Can't execute '$sql': ".$sth->errstr() );
$sth->finish(); $sth->finish();
if ( $ZoneMinder::Database::dbh->errstr() ) {
$ZoneMinder::Database::dbh->commit();
return;
}
$event->delete_files( ); $event->delete_files( );
} else { } else {
Debug('Not deleting frames, stats and files for speed.'); Debug('Not deleting frames, stats and files for speed.');
} }
# Do it individually to avoid locking up the table for new events
my $sql = 'DELETE FROM Events WHERE Id=?';
my $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql )
or Error( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() );
my $res = $sth->execute( $event->{Id} )
or Error( "Can't execute '$sql': ".$sth->errstr() );
$sth->finish();
$ZoneMinder::Database::dbh->commit();
} # end sub delete } # end sub delete
sub delete_files { sub delete_files {
@ -502,7 +526,10 @@ sub MoveTo {
} }
} }
} }
return $error if $error; if ( $error ) {
$ZoneMinder::Database::dbh->commit();
return $error;
}
my @files = glob("$OldPath/*"); my @files = glob("$OldPath/*");
for my $file (@files) { for my $file (@files) {

View File

@ -140,7 +140,7 @@ sub Sql {
M.DefaultScale M.DefaultScale
FROM Events as E FROM Events as E
INNER JOIN Monitors as M on M.Id = E.MonitorId INNER JOIN Monitors as M on M.Id = E.MonitorId
INNER JOIN Storage as S on S.Id = E.StorageId LEFT JOIN Storage as S on S.Id = E.StorageId
'; ';
$self->{Sql} = ''; $self->{Sql} = '';

View File

@ -42,17 +42,26 @@ use ZoneMinder::Config qw(:all);
use ZoneMinder::Logger qw(:all); use ZoneMinder::Logger qw(:all);
use ZoneMinder::Database qw(:all); use ZoneMinder::Database qw(:all);
use vars qw/ $AUTOLOAD $log $dbh/; use vars qw/ $AUTOLOAD $log $dbh %cache $no_cache/;
*log = \$ZoneMinder::Logger::logger; *log = \$ZoneMinder::Logger::logger;
*dbh = \$ZoneMinder::Database::dbh; *dbh = \$ZoneMinder::Database::dbh;
my $debug = 0; my $debug = 0;
use constant DEBUG_ALL=>1; $no_cache = 0;
use constant DEBUG_ALL=>0;
sub init_cache {
$no_cache = 0;
%cache = ();
} # end sub init_cache
sub new { sub new {
my ( $parent, $id, $data ) = @_; my ( $parent, $id, $data ) = @_;
$cache{$parent} = {} if ! $cache{$parent};
my $sub_cache = $cache{$parent};
my $self = {}; my $self = {};
bless $self, $parent; bless $self, $parent;
no strict 'refs'; no strict 'refs';
@ -61,10 +70,23 @@ sub new {
Error( 'NO primary_key for type ' . $parent ); Error( 'NO primary_key for type ' . $parent );
return; return;
} # end if } # end if
if ( $id and (!$no_cache) and $$sub_cache{$id} ) {
if ( $data ) {
# The reason to use load is if we have overriden it in the object,
$$sub_cache{$id}->load( $data );
}
return $$sub_cache{$id};
}
if ( ( $$self{$primary_key} = $id ) or $data ) { if ( ( $$self{$primary_key} = $id ) or $data ) {
#$log->debug("loading $parent $id") if $debug or DEBUG_ALL; #$log->debug("loading $parent $id") if $debug or DEBUG_ALL;
$self->load( $data ); $self->load( $data );
} if ( !$no_cache ) {
$$sub_cache{$id} = $self;
} # end if
} # end if
return $self; return $self;
} # end sub new } # end sub new
@ -170,8 +192,6 @@ sub save {
foreach my $k ( keys %$data ) { foreach my $k ( keys %$data ) {
$log->debug("Object::save after set $k => $$data{$k} $$self{$k}"); $log->debug("Object::save after set $k => $$data{$k} $$self{$k}");
} }
} else {
$log->debug("No data after set");
} }
} }
#$debug = 0; #$debug = 0;
@ -430,6 +450,13 @@ sub transform {
return $value; return $value;
} # end sub transform } # end sub transform
sub to_string {
my $type = ref($_[0]);
my $fields = eval '\%'.$type.'::fields';
return $type . ': '. join(' ' , map { $_[0]{$_} ? "$_ => $_[0]{$_}" : () } keys %$fields );
}
1; 1;
__END__ __END__

View File

@ -30,6 +30,7 @@ use warnings;
require ZoneMinder::Base; require ZoneMinder::Base;
require ZoneMinder::Object; require ZoneMinder::Object;
require ZoneMinder::Server;
use parent qw(Exporter ZoneMinder::Object); use parent qw(Exporter ZoneMinder::Object);
@ -59,6 +60,10 @@ sub find {
my @sql_filters; my @sql_filters;
my @sql_values; my @sql_values;
if ( exists $sql_filters{Id} ) {
push @sql_filters , ' Id=? ';
push @sql_values, $sql_filters{Id};
}
if ( exists $sql_filters{Name} ) { if ( exists $sql_filters{Name} ) {
push @sql_filters , ' Name = ? '; push @sql_filters , ' Name = ? ';
push @sql_values, $sql_filters{Name}; push @sql_values, $sql_filters{Name};
@ -108,6 +113,14 @@ sub Name {
return $_[0]{Name}; return $_[0]{Name};
} # end sub Path } # end sub Path
sub Server {
my $self = shift;
if ( ! $$self{Server} ) {
$$self{Server} = new ZoneMinder::Server( $$self{ServerId} );
}
return $$self{Server};
}
1; 1;
__END__ __END__
# Below is stub documentation for your module. You'd better edit it! # Below is stub documentation for your module. You'd better edit it!

View File

@ -55,7 +55,6 @@ use constant EVENT_PATH => ($Config{ZM_DIR_EVENTS}=~m|/|)
; ;
use constant ZM_AUDIT_PID => '@ZM_RUNDIR@/zmaudit.pid'; use constant ZM_AUDIT_PID => '@ZM_RUNDIR@/zmaudit.pid';
$| = 1;
$ENV{PATH} = '/bin:/usr/bin:/usr/local/bin'; $ENV{PATH} = '/bin:/usr/bin:/usr/local/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL}; $ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
@ -67,6 +66,7 @@ my $continuous = 0;
my $monitor_id = 0; my $monitor_id = 0;
my $version; my $version;
my $force = 0; my $force = 0;
my $storage_id = undef;
logInit(); logInit();
@ -74,8 +74,9 @@ GetOptions(
continuous =>\$continuous, continuous =>\$continuous,
force =>\$force, force =>\$force,
interactive =>\$interactive, interactive =>\$interactive,
monitor_id =>\$monitor_id, 'monitor_id=i' =>\$monitor_id,
report =>\$report, report =>\$report,
'storage_id=i' =>\$storage_id,
version =>\$version version =>\$version
) or pod2usage(-exitstatus => -1); ) or pod2usage(-exitstatus => -1);
@ -119,6 +120,9 @@ sub HupHandler {
} }
sub TermHandler { sub TermHandler {
Info("Received TERM, exiting"); Info("Received TERM, exiting");
Term();
}
sub Term {
unlink ZM_AUDIT_PID; unlink ZM_AUDIT_PID;
exit( 0 ); exit( 0 );
} }
@ -128,6 +132,8 @@ $SIG{INT} = \&TermHandler;
my $dbh = zmDbConnect(); my $dbh = zmDbConnect();
$| = 1;
require ZoneMinder::Monitor; require ZoneMinder::Monitor;
require ZoneMinder::Storage; require ZoneMinder::Storage;
require ZoneMinder::Event; require ZoneMinder::Event;
@ -165,6 +171,21 @@ MAIN: while( $loop ) {
} # end if } # end if
} # end while can't connect to the db } # end while can't connect to the db
my @Storage_Areas;
if ( defined $storage_id ) {
@Storage_Areas = ZoneMinder::Storage->find( Id=>$storage_id );
if ( !@Storage_Areas ) {
Fatal("No Storage Area found with Id $storage_id");
}
Info("Auditing Storage Area $Storage_Areas[0]{Id} $Storage_Areas[0]{Name} at $Storage_Areas[0]{Path}");
} elsif ( $Config{ZM_SERVER_ID} ) {
@Storage_Areas = ZoneMinder::Storage->find( ServerId => $Config{ZM_SERVER_ID} );
Info("Auditing All Storage Areas on Server " . $Storage_Areas[0]->Server()->Name());
} else {
@Storage_Areas = ZoneMinder::Storage->find();
Info("Auditing All Storage Areas");
}
my %Monitors; my %Monitors;
my $db_monitors; my $db_monitors;
my $monitorSelectSql = $monitor_id ? 'SELECT * FROM Monitors WHERE Id=?' : 'SELECT * FROM Monitors ORDER BY Id'; my $monitorSelectSql = $monitor_id ? 'SELECT * FROM Monitors WHERE Id=?' : 'SELECT * FROM Monitors ORDER BY Id';
@ -182,21 +203,19 @@ MAIN: while( $loop ) {
while( my $monitor = $monitorSelectSth->fetchrow_hashref() ) { while( my $monitor = $monitorSelectSth->fetchrow_hashref() ) {
$Monitors{$$monitor{Id}} = $monitor; $Monitors{$$monitor{Id}} = $monitor;
Debug( "Found database monitor '$monitor->{Id}'" );
my $db_events = $db_monitors->{$monitor->{Id}} = {}; my $db_events = $db_monitors->{$monitor->{Id}} = {};
my $res = $eventSelectSth->execute( $monitor->{Id} ) my $res = $eventSelectSth->execute( $monitor->{Id} )
or Fatal( "Can't execute: ".$eventSelectSth->errstr() ); or Fatal( "Can't execute: ".$eventSelectSth->errstr() );
while ( my $event = $eventSelectSth->fetchrow_hashref() ) { while ( my $event = $eventSelectSth->fetchrow_hashref() ) {
$db_events->{$event->{Id}} = $event->{Age}; $db_events->{$event->{Id}} = $event->{Age};
} }
Debug( 'Got '.int(keys(%$db_events))." events\n" ); Debug( 'Got '.int(keys(%$db_events))." events for monitor $monitor->{Id}" );
} }
my $fs_monitors; my $fs_monitors;
foreach my $Storage (
ZoneMinder::Storage->find( ($Config{ZM_SERVER_ID} ? ( ServerId => $Config{ZM_SERVER_ID} ) : () ) ), foreach my $Storage ( @Storage_Areas ) {
) {
Debug('Checking events in ' . $Storage->Path() ); Debug('Checking events in ' . $Storage->Path() );
if ( ! chdir( $Storage->Path() ) ) { if ( ! chdir( $Storage->Path() ) ) {
Error( 'Unable to change dir to ' . $Storage->Path() ); Error( 'Unable to change dir to ' . $Storage->Path() );
@ -214,8 +233,8 @@ MAIN: while( $loop ) {
# De-taint # De-taint
( my $monitor_dir ) = ( $monitor =~ /^(.*)$/ ); ( my $monitor_dir ) = ( $monitor =~ /^(.*)$/ );
if ( $$Storage{Scheme} eq 'Deep' ) { #if ( $$Storage{Scheme} eq 'Deep' ) {
foreach my $day_dir ( glob("$monitor_dir/*/*/*") ) { foreach my $day_dir ( glob("$monitor_dir/[0-9][0-9]/[0-9][0-9]/[0-9][0-9]") ) {
Debug( "Checking day dir $day_dir" ); Debug( "Checking day dir $day_dir" );
( $day_dir ) = ( $day_dir =~ /^(.*)$/ ); # De-taint ( $day_dir ) = ( $day_dir =~ /^(.*)$/ ); # De-taint
if ( ! chdir( $day_dir ) ) { if ( ! chdir( $day_dir ) ) {
@ -252,6 +271,7 @@ MAIN: while( $loop ) {
$$Event{Id} = $event; $$Event{Id} = $event;
$$Event{Path} = join('/', $Storage->Path(), $day_dir,$event_path); $$Event{Path} = join('/', $Storage->Path(), $day_dir,$event_path);
$$Event{RelativePath} = join('/', $day_dir,$event_path); $$Event{RelativePath} = join('/', $day_dir,$event_path);
$$Event{Scheme} = 'Deep';
$Event->MonitorId( $monitor_dir ); $Event->MonitorId( $monitor_dir );
$Event->StorageId( $Storage->Id() ); $Event->StorageId( $Storage->Id() );
$Event->DiskSpace( undef ); $Event->DiskSpace( undef );
@ -259,8 +279,8 @@ MAIN: while( $loop ) {
} # end foreach event_link } # end foreach event_link
chdir( $Storage->Path() ); chdir( $Storage->Path() );
} # end foreach day dir } # end foreach day dir
} elsif ( $$Storage{Scheme} eq 'Medium' ) {
foreach my $event_dir ( glob("$monitor_dir/*/*") ) { foreach my $event_dir ( glob("$monitor_dir/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/*") ) {
next if ! -d $event_dir; next if ! -d $event_dir;
my ( $date, $event_id ) = $event_dir =~ /^$monitor_dir\/(\d{4}\-\d{2}\-\d{2})\/(\d+)$/; my ( $date, $event_id ) = $event_dir =~ /^$monitor_dir\/(\d{4}\-\d{2}\-\d{2})\/(\d+)$/;
if ( ! $event_id ) { if ( ! $event_id ) {
@ -270,11 +290,13 @@ MAIN: while( $loop ) {
my $Event = $fs_events->{$event_id} = new ZoneMinder::Event(); my $Event = $fs_events->{$event_id} = new ZoneMinder::Event();
$$Event{Id} = $event_id; $$Event{Id} = $event_id;
$$Event{Path} = join('/', $Storage->Path(), $event_dir ); $$Event{Path} = join('/', $Storage->Path(), $event_dir );
$$Event{Scheme} = 'Medium';
$$Event{RelativePath} = $event_dir; $$Event{RelativePath} = $event_dir;
$Event->MonitorId( $monitor_dir ); $Event->MonitorId( $monitor_dir );
$Event->StorageId( $Storage->Id() ); $Event->StorageId( $Storage->Id() );
} # end foreach event } # end foreach event
} else {
if ( ! $$Storage{Scheme} ) {
if ( ! chdir( $monitor_dir ) ) { if ( ! chdir( $monitor_dir ) ) {
Error( "Can't chdir directory '$$Storage{Path}/$monitor_dir': $!" ); Error( "Can't chdir directory '$$Storage{Path}/$monitor_dir': $!" );
next; next;
@ -310,7 +332,6 @@ MAIN: while( $loop ) {
my $Event = $fs_events->{$fs_event_id}; my $Event = $fs_events->{$fs_event_id};
if ( ! defined( $db_events->{$fs_event_id} ) ) { if ( ! defined( $db_events->{$fs_event_id} ) ) {
my $age = $Event->age(); my $age = $Event->age();
@ -373,12 +394,12 @@ MAIN: while( $loop ) {
while ( my ( $db_event, $age ) = each( %$db_events ) ) { while ( my ( $db_event, $age ) = each( %$db_events ) ) {
if ( ! defined( $fs_events->{$db_event} ) ) { if ( ! defined( $fs_events->{$db_event} ) ) {
Debug("Event $db_event is not in fs.");
my $Event = ZoneMinder::Event->find_one( Id=>$db_event ); my $Event = ZoneMinder::Event->find_one( Id=>$db_event );
if ( ! $Event ) { if ( ! $Event ) {
Debug("Event $db_event is no longer in db. Filter probably deleted it while we were auditing."); Debug("Event $db_event is no longer in db. Filter probably deleted it while we were auditing.");
next; next;
} }
Debug("Event $db_event is not in fs. Should have been at ".$Event->Path());
if ( ! $Event->StartTime() ) { if ( ! $Event->StartTime() ) {
Info("Event $$Event{Id} has no start time. deleting it."); Info("Event $$Event{Id} has no start time. deleting it.");
if ( confirm() ) { if ( confirm() ) {
@ -401,15 +422,13 @@ MAIN: while( $loop ) {
Debug("Database event $$Event{Id} apparently exists at " . $Event->Path() ); Debug("Database event $$Event{Id} apparently exists at " . $Event->Path() );
} else { } else {
if ( $age > $Config{ZM_AUDIT_MIN_AGE} ) { if ( $age > $Config{ZM_AUDIT_MIN_AGE} ) {
aud_print( "Database event '$db_monitor/$db_event' does not exist at " . $Event->Path().' in filesystem' ); aud_print( "Database event '$db_monitor/$db_event' does not exist at " . $Event->Path().' in filesystem, deleting' );
if ( confirm() ) { if ( confirm() ) {
$Event->delete(); $Event->delete();
$cleaned = 1; $cleaned = 1;
} }
} else { } else {
my $Storage = $Event->Storage(); aud_print( "Database event '".$Event->Path()." monitor:$db_monitor event:$db_event' does not exist in filesystem but too young to delete age: $age > MIN $Config{ZM_AUDIT_MIN_AGE}.\n" );
aud_print( "Database event '".$Event->getPath()." monitor:$db_monitor event:$db_event' does not exist in filesystem but too young to delete age: $age > MIN $Config{ZM_AUDIT_MIN_AGE}.\n" );
} }
} # end if exists in filesystem } # end if exists in filesystem
} # end if ! in fs_events } # end if ! in fs_events
@ -651,7 +670,7 @@ $eventcounts_sth->finish();
sleep( $Config{ZM_AUDIT_CHECK_INTERVAL} ) if $continuous; sleep( $Config{ZM_AUDIT_CHECK_INTERVAL} ) if $continuous;
}; };
term_handler(); Term();
sub aud_print { sub aud_print {
my $string = shift; my $string = shift;
@ -766,6 +785,7 @@ yet.
-f, --force - Run even if pid file exists -f, --force - Run even if pid file exists
-i, --interactive - Ask before applying any changes -i, --interactive - Ask before applying any changes
-r, --report - Just report don't actually do anything -r, --report - Just report don't actually do anything
-s, --storage_id - Specify a storage area to audit instead of all
-v, --version - Print the installed version of ZoneMinder -v, --version - Print the installed version of ZoneMinder
=cut =cut

View File

@ -185,7 +185,7 @@ use Sys::CpuLoad;
my $attempts = 0; my $attempts = 0;
while( !connect( CLIENT, $saddr ) ) { while( !connect( CLIENT, $saddr ) ) {
$attempts++; $attempts++;
Error("Waiting for zmdc.pl server process at " . SOCK_FILE.", attempt $attempts" ); Debug("Waiting for zmdc.pl server process at ".SOCK_FILE.", attempt $attempts" );
Fatal( "Can't connect: $!" ) if ($attempts > MAX_CONNECT_DELAY); Fatal( "Can't connect: $!" ) if ($attempts > MAX_CONNECT_DELAY);
usleep(200000); usleep(200000);
} # end while } # end while
@ -566,13 +566,19 @@ sub restart {
my $command = $daemon; my $command = $daemon;
$command .= ' '.join( ' ', ( @args ) ) if @args; $command .= ' '.join( ' ', ( @args ) ) if @args;
dPrint ( ZoneMinder::Logger::WARNING, "Restarting $command\n");
my $process = $cmd_hash{$command}; my $process = $cmd_hash{$command};
if ( $process ) { if ( $process ) {
dPrint ( ZoneMinder::Logger::WARNING, "Have process" );
if ( $process->{pid} ) { if ( $process->{pid} ) {
dPrint ( ZoneMinder::Logger::WARNING, "Have process pid " .$process->{pid} );
my $cpid = $process->{pid}; my $cpid = $process->{pid};
if ( defined($pid_hash{$cpid}) ) { if ( defined($pid_hash{$cpid}) ) {
dPrint ( ZoneMinder::Logger::WARNING, "Have process pid hash " .$process->{pid} );
_stop( 0, $process ); _stop( 0, $process );
return; return;
} else {
dPrint ( ZoneMinder::Logger::WARNING, "Not sending stop" );
} }
} }
} }

View File

@ -153,7 +153,10 @@ my $eventcounts_week_sth = $dbh->prepare_cached( $eventcounts_week_sql );
my $eventcounts_month_sth = $dbh->prepare_cached( $eventcounts_month_sql ); my $eventcounts_month_sth = $dbh->prepare_cached( $eventcounts_month_sql );
while( 1 ) { while( 1 ) {
$dbh->ping(); while ( ! ( $dbh and $dbh->ping() ) ) {
Info("Reconnecting to db");
$dbh = zmDbConnect();
}
$dbh->do('DELETE FROM Events_Hour WHERE StartTime < DATE_SUB(NOW(), INTERVAL 1 hour)'); $dbh->do('DELETE FROM Events_Hour WHERE StartTime < DATE_SUB(NOW(), INTERVAL 1 hour)');
$dbh->do('DELETE FROM Events_Day WHERE StartTime < DATE_SUB(NOW(), INTERVAL 1 day)'); $dbh->do('DELETE FROM Events_Day WHERE StartTime < DATE_SUB(NOW(), INTERVAL 1 day)');

View File

@ -159,7 +159,7 @@ if ( $check && $Config{ZM_CHECK_FOR_UPDATES} ) {
my $ua = LWP::UserAgent->new; my $ua = LWP::UserAgent->new;
$ua->agent( "ZoneMinder Update Agent/".ZM_VERSION ); $ua->agent( "ZoneMinder Update Agent/".ZM_VERSION );
if ( $Config{ZM_UPDATE_CHECK_PROXY} ) { if ( $Config{ZM_UPDATE_CHECK_PROXY} ) {
$ua->proxy( "http", $Config{ZM_UPDATE_CHECK_PROXY} ); $ua->proxy( 'http', $Config{ZM_UPDATE_CHECK_PROXY} );
} }
my $req = HTTP::Request->new( GET=>'https://update.zoneminder.com/version.txt' ); my $req = HTTP::Request->new( GET=>'https://update.zoneminder.com/version.txt' );
my $res = $ua->request($req); my $res = $ua->request($req);
@ -224,7 +224,7 @@ if ( $zoneFix ) {
} }
$sth->finish(); $sth->finish();
$sql = "update Zones set MinAlarmPixels = ?, MaxAlarmPixels = ?, MinFilterPixels = ?, MaxFilterPixels = ?, MinBlobPixels = ?, MaxBlobPixels = ? where Id = ?"; $sql = 'update Zones set MinAlarmPixels = ?, MaxAlarmPixels = ?, MinFilterPixels = ?, MaxFilterPixels = ?, MinBlobPixels = ?, MaxBlobPixels = ? where Id = ?';
$sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
foreach my $zone ( @zones ) { foreach my $zone ( @zones ) {
my $zone_width = (($zone->{HiX}*$zone->{MonitorWidth})-($zone->{LoX}*$zone->{MonitorWidth}))/100; my $zone_width = (($zone->{HiX}*$zone->{MonitorWidth})-($zone->{LoX}*$zone->{MonitorWidth}))/100;
@ -378,7 +378,7 @@ if ( $version ) {
if ( $response =~ /^[yY]$/ ) { if ( $response =~ /^[yY]$/ ) {
my ( $host, $portOrSocket ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ ); my ( $host, $portOrSocket ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ );
my $command = "mysqldump"; my $command = 'mysqldump';
if ( defined($portOrSocket) ) { if ( defined($portOrSocket) ) {
if ( $portOrSocket =~ /^\// ) { if ( $portOrSocket =~ /^\// ) {
$command .= " -S".$portOrSocket; $command .= " -S".$portOrSocket;
@ -503,7 +503,7 @@ if ( $version ) {
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
while( my $monitor = $sth->fetchrow_hashref() ) { while( my $monitor = $sth->fetchrow_hashref() ) {
my $sql = "update Events set Width = ?, Height = ? where MonitorId = ?"; my $sql = 'update Events set Width = ?, Height = ? where MonitorId = ?';
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( $monitor->{Width}, $monitor->{Height}, $monitor->{Id} ) or die( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute( $monitor->{Width}, $monitor->{Height}, $monitor->{Id} ) or die( "Can't execute: ".$sth->errstr() );
} }
@ -518,7 +518,7 @@ if ( $version ) {
my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
my $sequence = 1; my $sequence = 1;
while( my $monitor = $sth->fetchrow_hashref() ) { while( my $monitor = $sth->fetchrow_hashref() ) {
my $sql = "update Monitors set Sequence = ? where Id = ?"; my $sql = 'update Monitors set Sequence = ? where Id = ?';
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( $sequence++, $monitor->{Id} ) or die( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute( $sequence++, $monitor->{Id} ) or die( "Can't execute: ".$sth->errstr() );
} }
@ -536,7 +536,7 @@ if ( $version ) {
push( @filters, $filter ); push( @filters, $filter );
} }
$sth->finish(); $sth->finish();
$sql = "update Filters set Query = ? where Name = ?"; $sql = 'update Filters set Query = ? where Name = ?';
$sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
foreach my $filter ( @filters ) { foreach my $filter ( @filters ) {
if ( $filter->{Query} =~ /op\d=&/ ) { if ( $filter->{Query} =~ /op\d=&/ ) {
@ -569,7 +569,7 @@ if ( $version ) {
no strict 'refs'; no strict 'refs';
foreach my $zone ( @zones ) { foreach my $zone ( @zones ) {
# Create the coordinate strings # Create the coordinate strings
if ( $zone->{Units} eq "Pixels" ) { if ( $zone->{Units} eq 'Pixels' ) {
my $sql = "update Zones set NumCoords = 4, Coords = concat( LoX,',',LoY,' ',HiX,',',LoY,' ',HiX,',',HiY,' ',LoX,',',HiY ), Area = round( ((HiX-LoX)+1)*((HiY-LoY)+1) ) where Id = ?"; my $sql = "update Zones set NumCoords = 4, Coords = concat( LoX,',',LoY,' ',HiX,',',LoY,' ',HiX,',',HiY,' ',LoX,',',HiY ), Area = round( ((HiX-LoX)+1)*((HiY-LoY)+1) ) where Id = ?";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( $zone->{Id} ) or die( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute( $zone->{Id} ) or die( "Can't execute: ".$sth->errstr() );
@ -604,7 +604,7 @@ if ( $version ) {
foreach my $defn ( split( /,/, $state->{Definition} ) ) { foreach my $defn ( split( /,/, $state->{Definition} ) ) {
push( @new_defns, $defn.":1" ); push( @new_defns, $defn.":1" );
} }
my $sql = "update States set Definition = ? where Name = ?"; my $sql = 'update States set Definition = ? where Name = ?';
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( join( ',', @new_defns ), $state->{Name} ) or die( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute( join( ',', @new_defns ), $state->{Name} ) or die( "Can't execute: ".$sth->errstr() );
} }
@ -684,7 +684,7 @@ if ( $version ) {
$db_monitor->{LabelFormat} =~ s/\%\%s/%N/; $db_monitor->{LabelFormat} =~ s/\%\%s/%N/;
$db_monitor->{LabelFormat} =~ s/\%\%s/%Q/; $db_monitor->{LabelFormat} =~ s/\%\%s/%Q/;
my $sql = "update Monitors set LabelFormat = ? where Id = ?"; my $sql = 'update Monitors set LabelFormat = ? where Id = ?';
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( $db_monitor->{LabelFormat}, $db_monitor->{Id} ) or die( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute( $db_monitor->{LabelFormat}, $db_monitor->{Id} ) or die( "Can't execute: ".$sth->errstr() );
} }
@ -743,7 +743,7 @@ if ( $version ) {
$i++; $i++;
} }
$newQuery .= '}'; $newQuery .= '}';
foreach my $field ( "sort_field", "sort_asc", "limit" ) { foreach my $field ( 'sort_field', 'sort_asc', 'limit' ) {
if ( defined($filter->{$field}) ) { if ( defined($filter->{$field}) ) {
$newQuery .= 's:'.length($field).':"'.$field.'";'; $newQuery .= 's:'.length($field).':"'.$field.'";';
$newQuery .= 's:'.length($filter->{$field}).':"'.$filter->{$field}.'";'; $newQuery .= 's:'.length($filter->{$field}).':"'.$filter->{$field}.'";';
@ -751,7 +751,7 @@ if ( $version ) {
} }
$newQuery .= '}'; $newQuery .= '}';
my $sql = "update Filters set Query = ? where Name = ?"; my $sql = 'update Filters set Query = ? where Name = ?';
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( $newQuery, $dbFilter->{Name} ) or die( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute( $newQuery, $dbFilter->{Name} ) or die( "Can't execute: ".$sth->errstr() );
} }
@ -829,7 +829,7 @@ if ( $version ) {
my $phpQuery = $dbFilter->{Query}; my $phpQuery = $dbFilter->{Query};
my $query = PHP::Serialization::unserialize( $phpQuery ); my $query = PHP::Serialization::unserialize( $phpQuery );
my $jsonQuery = jsonEncode( $query ); my $jsonQuery = jsonEncode( $query );
my $sql = "update Filters set Query = ? where Name = ?"; my $sql = 'update Filters set Query = ? where Name = ?';
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( $jsonQuery, $dbFilter->{Name} ) or die( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute( $jsonQuery, $dbFilter->{Name} ) or die( "Can't execute: ".$sth->errstr() );
}; };
@ -851,7 +851,7 @@ if ( $version ) {
# Copy the FTP specific values to the new general config # Copy the FTP specific values to the new general config
my $fetchSql = "select * from Config where Name like 'ZM_UPLOAD_FTP_%'"; my $fetchSql = "select * from Config where Name like 'ZM_UPLOAD_FTP_%'";
my $fetchSth = $dbh->prepare_cached( $fetchSql ) or die( "Can't prepare '$fetchSql': ".$dbh->errstr() ); my $fetchSth = $dbh->prepare_cached( $fetchSql ) or die( "Can't prepare '$fetchSql': ".$dbh->errstr() );
my $updateSql = "update Config set Value = ? where Name = ?"; my $updateSql = 'update Config set Value = ? where Name = ?';
my $updateSth = $dbh->prepare_cached( $updateSql ) or die( "Can't prepare '$updateSql': ".$dbh->errstr() ); my $updateSth = $dbh->prepare_cached( $updateSql ) or die( "Can't prepare '$updateSql': ".$dbh->errstr() );
my $fetchRes = $fetchSth->execute() or die( "Can't execute: ".$fetchSth->errstr() ); my $fetchRes = $fetchSth->execute() or die( "Can't execute: ".$fetchSth->errstr() );
while( my $config = $fetchSth->fetchrow_hashref() ) { while( my $config = $fetchSth->fetchrow_hashref() ) {
@ -881,7 +881,7 @@ if ( $version ) {
if ( $version ge '1.26.0' ) { if ( $version ge '1.26.0' ) {
my @files; my @files;
$updateDir = $Config{ZM_PATH_DATA}."/db" if ! $updateDir; $updateDir = $Config{ZM_PATH_DATA}.'/db' if ! $updateDir;
opendir( my $dh, $updateDir ) || die "Can't open updateDir $!"; opendir( my $dh, $updateDir ) || die "Can't open updateDir $!";
#@files = sort grep { (!/^\./) && /^zm_update\-[\d\.]+\.sql$/ && -f "$updateDir/$_" } readdir($dh); #@files = sort grep { (!/^\./) && /^zm_update\-[\d\.]+\.sql$/ && -f "$updateDir/$_" } readdir($dh);
#PP - use perl version sort #PP - use perl version sort
@ -895,29 +895,28 @@ if ( $version ) {
die "Should have found upgrade scripts at $updateDir\n"; die "Should have found upgrade scripts at $updateDir\n";
} # end if } # end if
$dbh->{'AutoCommit'} = 0;
foreach my $patch ( @files ) { foreach my $patch ( @files ) {
my ( $v ) = $patch =~ /^zm_update\-([\d\.]+)\.sql$/; my ( $v ) = $patch =~ /^zm_update\-([\d\.]+)\.sql$/;
#PP make sure we use version compare #PP make sure we use version compare
if ( version->parse('v' . $v) > version->parse('v' . $version) ) { if ( version->parse('v' . $v) > version->parse('v' . $version) ) {
print( "Upgrading DB to $v from $version\n" ); print( "Upgrading DB to $v from $version\n" );
patchDB( $dbh, $v ); patchDB( $dbh, $v );
if ( $dbh->errstr() ) { my $sql = "update Config set Value = ? where Name = 'ZM_DYN_DB_VERSION'";
$dbh->rollback(); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
die "Error: " . $dbh->errstr(). ". Rolled back.\n"; my $res = $sth->execute( $version ) or die( "Can't execute: ".$sth->errstr() );
} # end if error $sth->finish();
} # end if #patchDB_using_do( $dbh, $version, $updateDir.'/'.$patch );
} # end if newer version
} # end foreach patchfile } # end foreach patchfile
$dbh->{'AutoCommit'} = 1;
$cascade = !undef; $cascade = !undef;
} # end if } # end if
if ( $cascade ) { if ( $cascade ) {
my $installed_version = ZM_VERSION; my $installed_version = ZM_VERSION;
my $sql = "update Config set Value = ? where Name = ?"; my $sql = 'update Config set Value = ? where Name = ?';
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( "$installed_version", "ZM_DYN_DB_VERSION" ) or die( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute( "$installed_version", 'ZM_DYN_DB_VERSION' ) or die( "Can't execute: ".$sth->errstr() );
$res = $sth->execute( "$installed_version", "ZM_DYN_CURR_VERSION" ) or die( "Can't execute: ".$sth->errstr() ); $res = $sth->execute( "$installed_version", 'ZM_DYN_CURR_VERSION' ) or die( "Can't execute: ".$sth->errstr() );
$sth->finish(); $sth->finish();
} else { } else {
zmDbDisconnect(); zmDbDisconnect();
@ -928,10 +927,36 @@ if ( $version ) {
zmDbDisconnect(); zmDbDisconnect();
exit( 0 ); exit( 0 );
sub patchDB_using_do {
my ( $dbh, $version, $file ) = @_;
open( my $fh, '<', $file ) or die "Unable to open $file $!";
$/ = undef;
my $sql = <$fh>;
close $fh;
if ( $sql ) {
$dbh->{'AutoCommit'} = 0;
$dbh->do($sql);
if ( $dbh->errstr() ) {
$dbh->rollback();
die "Error: " . $dbh->errstr(). ". Rolled back.\n";
} # end if error
my $sql = "update Config set Value = ? where Name = 'ZM_DYN_DB_VERSION'";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( $version ) or die( "Can't execute: ".$sth->errstr() );
$sth->finish();
$dbh->{'AutoCommit'} = 1;
} else {
Warning("Empty db update file at $file");
}
}
sub patchDB { sub patchDB {
my $dbh = shift; my $dbh = shift;
my $version = shift; my $version = shift;
my ( $host, $portOrSocket ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ ); my ( $host, $portOrSocket ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ );
my $command = 'mysql'; my $command = 'mysql';
if ( defined($portOrSocket) ) { if ( defined($portOrSocket) ) {
@ -966,10 +991,7 @@ sub patchDB {
die( "Command '$command' exited with status: $status\n" ); die( "Command '$command' exited with status: $status\n" );
} }
print( "\nDatabase successfully upgraded to version $version.\n" ); print( "\nDatabase successfully upgraded to version $version.\n" );
my $sql = "update Config set Value = ? where Name = 'ZM_DYN_DB_VERSION'";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( $version ) or die( "Can't execute: ".$sth->errstr() );
$sth->finish();
} }
sub migratePaths { sub migratePaths {

View File

@ -27,8 +27,12 @@ void FFMPEGInit() {
static bool bInit = false; static bool bInit = false;
if ( !bInit ) { if ( !bInit ) {
av_register_all(); if ( logDebugging() )
av_log_set_level( AV_LOG_DEBUG ); av_log_set_level( AV_LOG_DEBUG );
else
av_log_set_level( AV_LOG_QUIET );
av_register_all();
avformat_network_init();
bInit = true; bInit = true;
} }
} }
@ -107,8 +111,7 @@ static int parse_key_value_pair(AVDictionary **pm, const char **buf,
} }
int av_dict_parse_string(AVDictionary **pm, const char *str, int av_dict_parse_string(AVDictionary **pm, const char *str,
const char *key_val_sep, const char *pairs_sep, const char *key_val_sep, const char *pairs_sep,
int flags) int flags) {
{
if (!str) if (!str)
return 0; return 0;
@ -188,18 +191,18 @@ int hacked_up_context2_for_older_ffmpeg(AVFormatContext **avctx, AVOutputFormat
if (ret) { if (ret) {
avformat_free_context(s); avformat_free_context(s);
return ret; return ret;
} else { }
s->oformat = oformat; s->oformat = oformat;
#if 1 #if 0
// This is some very wrong code, and I don't think it is neccessary
if (s->oformat->priv_data_size > 0) { if (s->oformat->priv_data_size > 0) {
s->priv_data = av_mallocz(s->oformat->priv_data_size);
if (s->priv_data) {
if (s->oformat->priv_class) { if (s->oformat->priv_class) {
// This looks wrong, we just allocated priv_data and now we are losing the pointer to it.FIXME
*(const AVClass**)s->priv_data = s->oformat->priv_class; *(const AVClass**)s->priv_data = s->oformat->priv_class;
av_opt_set_defaults(s->priv_data); av_opt_set_defaults(s->priv_data);
}
} else { } else {
s->priv_data = av_mallocz(s->oformat->priv_data_size);
if ( ! s->priv_data) {
av_log(s, AV_LOG_ERROR, "Out of memory\n"); av_log(s, AV_LOG_ERROR, "Out of memory\n");
ret = AVERROR(ENOMEM); ret = AVERROR(ENOMEM);
return ret; return ret;
@ -212,7 +215,6 @@ int hacked_up_context2_for_older_ffmpeg(AVFormatContext **avctx, AVOutputFormat
*avctx = s; *avctx = s;
return 0; return 0;
} }
}
static void zm_log_fps(double d, const char *postfix) { static void zm_log_fps(double d, const char *postfix) {
uint64_t v = lrintf(d * 100); uint64_t v = lrintf(d * 100);
@ -228,22 +230,32 @@ static void zm_log_fps(double d, const char *postfix) {
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
void zm_dump_codecpar ( const AVCodecParameters *par ) { void zm_dump_codecpar ( const AVCodecParameters *par ) {
Debug(1, "Dumping codecpar codec_type(%d) codec_id(%d) codec_tag(%d) width(%d) height(%d)", Debug(1, "Dumping codecpar codec_type(%d) codec_id(%d) codec_tag(%d) width(%d) height(%d) bit_rate(%d) format(%d = %s)",
par->codec_type, par->codec_type,
par->codec_id, par->codec_id,
par->codec_tag, par->codec_tag,
par->width, par->width,
par->height par->height,
par->bit_rate,
par->format,
((AVPixelFormat)par->format == AV_PIX_FMT_NONE ? "none" : av_get_pix_fmt_name((AVPixelFormat)par->format))
); );
} }
#endif #endif
void zm_dump_codec ( const AVCodecContext *codec ) { void zm_dump_codec ( const AVCodecContext *codec ) {
Debug(1, "Dumping codecpar codec_type(%d) codec_id(%d) width(%d) height(%d)", Debug(1, "Dumping codec_context codec_type(%d) codec_id(%d) width(%d) height(%d) timebase(%d/%d) format(%s)",
codec->codec_type, codec->codec_type,
codec->codec_id, codec->codec_id,
codec->width, codec->width,
codec->height codec->height,
codec->time_base.num,
codec->time_base.den,
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
(codec->pix_fmt == AV_PIX_FMT_NONE ? "none" : av_get_pix_fmt_name(codec->pix_fmt))
#else
"unsupported on avconv"
#endif
); );
} }
@ -255,7 +267,6 @@ void zm_dump_stream_format(AVFormatContext *ic, int i, int index, int is_output)
AVStream *st = ic->streams[i]; AVStream *st = ic->streams[i];
AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0); AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
avcodec_string(buf, sizeof(buf), st->codec, is_output);
Debug(1, " Stream #%d:%d", index, i); Debug(1, " Stream #%d:%d", index, i);
/* the pid is an important information, so we display it */ /* the pid is an important information, so we display it */
@ -264,15 +275,21 @@ void zm_dump_stream_format(AVFormatContext *ic, int i, int index, int is_output)
Debug(1, "[0x%x]", st->id); Debug(1, "[0x%x]", st->id);
if (lang) if (lang)
Debug(1, "(%s)", lang->value); Debug(1, "(%s)", lang->value);
Debug(1, ", %d, %d/%d", st->codec_info_nb_frames, st->time_base.num, st->time_base.den); Debug(1, ", frames:%d, timebase: %d/%d", st->codec_info_nb_frames, st->time_base.num, st->time_base.den);
avcodec_string(buf, sizeof(buf), st->codec, is_output);
Debug(1, ": %s", buf); Debug(1, ": %s", buf);
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
AVCodecParameters *codec = st->codecpar;
#else
AVCodecContext *codec = st->codec;
#endif
if (st->sample_aspect_ratio.num && // default if (st->sample_aspect_ratio.num && // default
av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)) { av_cmp_q(st->sample_aspect_ratio, codec->sample_aspect_ratio)) {
AVRational display_aspect_ratio; AVRational display_aspect_ratio;
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den, av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
st->codec->width * (int64_t)st->sample_aspect_ratio.num, codec->width * (int64_t)st->sample_aspect_ratio.num,
st->codec->height * (int64_t)st->sample_aspect_ratio.den, codec->height * (int64_t)st->sample_aspect_ratio.den,
1024 * 1024); 1024 * 1024);
Debug(1, ", SAR %d:%d DAR %d:%d", Debug(1, ", SAR %d:%d DAR %d:%d",
st->sample_aspect_ratio.num, st->sample_aspect_ratio.den, st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
@ -337,8 +354,10 @@ int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt) {
#if LIBAVCODEC_VERSION_CHECK(56, 8, 0, 60, 100) #if LIBAVCODEC_VERSION_CHECK(56, 8, 0, 60, 100)
#else #else
unsigned int zm_av_packet_ref( AVPacket *dst, AVPacket *src ) { unsigned int zm_av_packet_ref( AVPacket *dst, AVPacket *src ) {
dst->data = reinterpret_cast<uint8_t*>(new uint64_t[(src->size + FF_INPUT_BUFFER_PADDING_SIZE)/sizeof(uint64_t) + 1]); dst->size = (src->size + FF_INPUT_BUFFER_PADDING_SIZE)/sizeof(uint64_t) + 1;
dst->data = reinterpret_cast<uint8_t*>(new uint64_t[dst->size]);
memcpy(dst->data, src->data, src->size ); memcpy(dst->data, src->data, src->size );
dst->flags = src->flags;
return 0; return 0;
} }
#endif #endif
@ -373,3 +392,71 @@ bool is_audio_stream( AVStream * stream ) {
} }
return false; return false;
} }
int zm_receive_frame( AVCodecContext *context, AVFrame *frame, AVPacket &packet ) {
int ret;
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
if ( (ret = avcodec_send_packet(context, &packet)) < 0 ) {
Error( "Unable to send packet %s, continuing",
av_make_error_string(ret).c_str() );
return 0;
}
#if HAVE_AVUTIL_HWCONTEXT_H
if ( hwaccel ) {
if ( (ret = avcodec_receive_frame(context, hwFrame)) < 0 ) {
Error( "Unable to receive frame %d: %s, continuing", streams[packet.stream_index].frame_count,
av_make_error_string(ret).c_str() );
return 0;
}
if ( (ret = av_hwframe_transfer_data(frame, hwFrame, 0)) < 0 ) {
Error( "Unable to transfer frame at frame %d: %s, continuing", streams[packet.stream_index].frame_count,
av_make_error_string(ret).c_str() );
return 0;
}
} else {
#endif
if ( (ret = avcodec_receive_frame(context, frame)) < 0 ) {
Error( "Unable to send packet %s, continuing", av_make_error_string(ret).c_str() );
return 0;
}
#if HAVE_AVUTIL_HWCONTEXT_H
}
#endif
# else
int frameComplete;
while ( !frameComplete ) {
if ( (ret = zm_avcodec_decode_video( context, frame, &frameComplete, &packet )) < 0 ) {
Error( "Unable to decode frame at frame: %s, continuing",
av_make_error_string(ret).c_str() );
return 0;
}
}
#endif
return 1;
} // end int zm_receive_frame( AVCodecContext *context, AVFrame *frame, AVPacket &packet )
void dumpPacket(AVPacket *pkt, const char *text) {
char b[10240];
snprintf(b, sizeof(b),
" pts: %" PRId64 ", dts: %" PRId64
", data: %p, size: %d, stream_index: %d, flags: %04x, keyframe(%d) pos: %" PRId64
", duration: %"
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
PRId64
#else
"d"
#endif
"\n",
pkt->pts,
pkt->dts,
pkt->data,
pkt->size,
pkt->stream_index,
pkt->flags,
pkt->flags & AV_PKT_FLAG_KEY,
pkt->pos,
pkt->duration);
Debug(1, "%s:%d:%s: %s", __FILE__, __LINE__, text, b);
}

View File

@ -237,9 +237,8 @@ enum _AVPIXELFORMAT GetFFMPEGPixelFormat(unsigned int p_colours, unsigned p_subp
*/ */
#ifdef __cplusplus #ifdef __cplusplus
inline static const std::string av_make_error_string(int errnum) inline static const std::string av_make_error_string(int errnum) {
{ static char errbuf[AV_ERROR_MAX_STRING_SIZE];
char errbuf[AV_ERROR_MAX_STRING_SIZE];
#if LIBAVUTIL_VERSION_CHECK(50, 13, 0, 13, 0) #if LIBAVUTIL_VERSION_CHECK(50, 13, 0, 13, 0)
av_strerror(errnum, errbuf, AV_ERROR_MAX_STRING_SIZE); av_strerror(errnum, errbuf, AV_ERROR_MAX_STRING_SIZE);
#else #else
@ -327,4 +326,6 @@ int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt);
bool is_video_stream( AVStream * stream ); bool is_video_stream( AVStream * stream );
bool is_audio_stream( AVStream * stream ); bool is_audio_stream( AVStream * stream );
int zm_receive_frame( AVCodecContext *context, AVFrame *frame, AVPacket &packet );
void dumpPacket(AVPacket *,const char *text="DEBUG");
#endif // ZM_FFMPEG_H #endif // ZM_FFMPEG_H

View File

@ -738,7 +738,8 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
int ret; int ret;
static char errbuf[AV_ERROR_MAX_STRING_SIZE]; static char errbuf[AV_ERROR_MAX_STRING_SIZE];
// If the reopen thread has a value, but mCanCapture != 0, then we have just reopened the connection to the ffmpeg device, and we can clean up the thread. // If the reopen thread has a value, but mCanCapture != 0, then we have just reopened
// the connection to the ffmpeg device, and we can clean up the thread.
if ( mReopenThread != 0 ) { if ( mReopenThread != 0 ) {
void *retval = 0; void *retval = 0;
@ -751,12 +752,10 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
mReopenThread = 0; mReopenThread = 0;
} }
int frameComplete = false; int frameComplete = false;
while ( ! frameComplete ) { while ( ! frameComplete ) {
av_init_packet( &packet ); av_init_packet( &packet );
Debug(4,"before read frame");
ret = av_read_frame( mFormatContext, &packet ); ret = av_read_frame( mFormatContext, &packet );
if ( ret < 0 ) { if ( ret < 0 ) {
av_strerror( ret, errbuf, AV_ERROR_MAX_STRING_SIZE ); av_strerror( ret, errbuf, AV_ERROR_MAX_STRING_SIZE );
@ -775,11 +774,7 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
} }
int keyframe = packet.flags & AV_PKT_FLAG_KEY; int keyframe = packet.flags & AV_PKT_FLAG_KEY;
dumpPacket(&packet);
Debug( 4, "Got packet from stream %d packet pts (%u) dts(%u), key?(%d)",
packet.stream_index, packet.pts, packet.dts,
keyframe
);
//Video recording //Video recording
if ( recording.tv_sec ) { if ( recording.tv_sec ) {
@ -841,6 +836,7 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
startTime, startTime,
this->getMonitor()); this->getMonitor());
} // end if record_audio } // end if record_audio
if ( ! videoStore->open() ) { if ( ! videoStore->open() ) {
delete videoStore; delete videoStore;
videoStore = NULL; videoStore = NULL;
@ -896,28 +892,18 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
if ( keyframe ) { if ( keyframe ) {
Debug(3, "Clearing queue"); Debug(3, "Clearing queue");
packetqueue.clearQueue( monitor->GetPreEventCount(), mVideoStreamId ); packetqueue.clearQueue( monitor->GetPreEventCount(), mVideoStreamId );
packetqueue.queuePacket( &packet );
} else if ( packetqueue.size() ) {
// it's a keyframe or we already have something in the queue
packetqueue.queuePacket( &packet );
} }
#if 0 } else if ( packet.stream_index == mAudioStreamId ) {
// Not sure this is valid. While a camera will PROBABLY always have an increasing pts... it doesn't have to.
// Also, I think there are integer wrap-around issues.
else if ( packet.pts && video_last_pts > packet.pts ) {
Warning( "Clearing queue due to out of order pts packet.pts(%d) < video_last_pts(%d)");
packetqueue.clearQueue();
}
#endif
}
// The following lines should ensure that the queue always begins with a video keyframe // The following lines should ensure that the queue always begins with a video keyframe
if ( packet.stream_index == mAudioStreamId ) {
//Debug(2, "Have audio packet, reocrd_audio is (%d) and packetqueue.size is (%d)", record_audio, packetqueue.size() ); //Debug(2, "Have audio packet, reocrd_audio is (%d) and packetqueue.size is (%d)", record_audio, packetqueue.size() );
if ( record_audio && packetqueue.size() ) { if ( record_audio && packetqueue.size() ) {
// if it's audio, and we are doing audio, and there is already something in the queue // if it's audio, and we are doing audio, and there is already something in the queue
packetqueue.queuePacket( &packet ); packetqueue.queuePacket( &packet );
} }
} else if ( packet.stream_index == mVideoStreamId ) {
if ( keyframe || packetqueue.size() ) // it's a keyframe or we already have something in the queue
packetqueue.queuePacket( &packet );
} }
} // end if recording or not } // end if recording or not

View File

@ -1205,7 +1205,7 @@ bool Monitor::Analyse() {
fps = double(fps_report_interval)/(now.tv_sec - last_fps_time); fps = double(fps_report_interval)/(now.tv_sec - last_fps_time);
Info( "%s: %d - Analysing at %.2f fps", name, image_count, fps ); Info( "%s: %d - Analysing at %.2f fps", name, image_count, fps );
static char sql[ZM_SQL_SML_BUFSIZ]; static char sql[ZM_SQL_SML_BUFSIZ];
snprintf( sql, sizeof(sql), "UPDATE Monitors SET AnalysisFPS = '%.2lf' WHERE Id = '%d'", fps, id ); snprintf( sql, sizeof(sql), "INSERT INTO Monitor_Status (Id,AnalysisFPS) VALUES (%d, %.2lf) ON DUPLICATE KEY UPDATE AnalysisFPS = %.2lf", id, fps, fps );
if ( mysql_query( &dbconn, sql ) ) { if ( mysql_query( &dbconn, sql ) ) {
Error( "Can't run query: %s", mysql_error( &dbconn ) ); Error( "Can't run query: %s", mysql_error( &dbconn ) );
} }
@ -3022,7 +3022,7 @@ Debug(4, "Return from Capture (%d)", captureResult);
Info( "%s: images:%d - Capturing at %.2lf fps", name, image_count, fps ); Info( "%s: images:%d - Capturing at %.2lf fps", name, image_count, fps );
last_fps_time = now; last_fps_time = now;
static char sql[ZM_SQL_SML_BUFSIZ]; static char sql[ZM_SQL_SML_BUFSIZ];
snprintf( sql, sizeof(sql), "UPDATE Monitors SET CaptureFPS='%.2lf' WHERE Id=%d", fps, id ); snprintf( sql, sizeof(sql), "INSERT INTO Monitor_Status (Id,CaptureFPS) VALUES (%d, %.2lf) ON DUPLICATE KEY UPDATE CaptureFPS = %.2lf", id, fps, fps );
if ( mysql_query( &dbconn, sql ) ) { if ( mysql_query( &dbconn, sql ) ) {
Error( "Can't run query: %s", mysql_error( &dbconn ) ); Error( "Can't run query: %s", mysql_error( &dbconn ) );
} }

View File

@ -88,7 +88,7 @@ unsigned int zm_packetqueue::clearQueue( unsigned int frames_to_keep, int stream
ZMPacket *zm_packet = *it; ZMPacket *zm_packet = *it;
AVPacket *av_packet = &(zm_packet->packet); AVPacket *av_packet = &(zm_packet->packet);
Debug(4, "Looking for keyframe at packet with stream index (%d) with keyframe (%d), frames_to_keep is (%d)", av_packet->stream_index, ( av_packet->flags & AV_PKT_FLAG_KEY ), frames_to_keep ); Debug(5, "Looking for keyframe at packet with stream index (%d) with keyframe (%d), frames_to_keep is (%d)", av_packet->stream_index, ( av_packet->flags & AV_PKT_FLAG_KEY ), frames_to_keep );
// Want frames_to_keep video keyframes. Otherwise, we may not have enough // Want frames_to_keep video keyframes. Otherwise, we may not have enough
if ( ( av_packet->stream_index == stream_id) && ( av_packet->flags & AV_PKT_FLAG_KEY ) ) { if ( ( av_packet->stream_index == stream_id) && ( av_packet->flags & AV_PKT_FLAG_KEY ) ) {
@ -157,7 +157,7 @@ void zm_packetqueue::clear_unwanted_packets( timeval *recording_started, int mVi
} }
} }
if ( it == pktQueue.rend() ) { if ( it == pktQueue.rend() ) {
Debug(1, "Didn't find a keyframe packet keeping all" ); Debug(1, "Didn't find a keyframe before event starttime. keeping all" );
return; return;
} }

View File

@ -36,8 +36,8 @@ Storage::Storage() {
} else { } else {
strncpy(path, staticConfig.DIR_EVENTS.c_str(), sizeof(path)-1 ); strncpy(path, staticConfig.DIR_EVENTS.c_str(), sizeof(path)-1 );
} }
scheme = DEEP; scheme = MEDIUM;
scheme_str = "Deep"; scheme_str = "Medium";
} }
Storage::Storage( MYSQL_ROW &dbrow ) { Storage::Storage( MYSQL_ROW &dbrow ) {
@ -93,6 +93,8 @@ Storage::Storage( unsigned int p_id ) {
} }
Debug(1,"No id passed to Storage constructor. Using default path %s instead", path ); Debug(1,"No id passed to Storage constructor. Using default path %s instead", path );
strcpy(name, "Default"); strcpy(name, "Default");
scheme = MEDIUM;
scheme_str = "Medium";
} }
} }

View File

@ -707,18 +707,6 @@ bool VideoStore::setup_resampler() {
#endif #endif
} // end bool VideoStore::setup_resampler() } // end bool VideoStore::setup_resampler()
void VideoStore::dumpPacket(AVPacket *pkt) {
char b[10240];
snprintf(b, sizeof(b),
" pts: %" PRId64 ", dts: %" PRId64
", data: %p, size: %d, sindex: %d, dflags: %04x, s-pos: %" PRId64
", c-duration: %d\n",
pkt->pts, pkt->dts, pkt->data, pkt->size, pkt->stream_index,
pkt->flags, pkt->pos, pkt->duration);
Debug(1, "%s:%d:DEBUG: %s", __FILE__, __LINE__, b);
}
int VideoStore::writeVideoFramePacket(AVPacket *ipkt) { int VideoStore::writeVideoFramePacket(AVPacket *ipkt) {
av_init_packet(&opkt); av_init_packet(&opkt);
@ -826,10 +814,7 @@ int VideoStore::writeVideoFramePacket(AVPacket *ipkt) {
AVPacket safepkt; AVPacket safepkt;
memcpy(&safepkt, &opkt, sizeof(AVPacket)); memcpy(&safepkt, &opkt, sizeof(AVPacket));
Debug(1, dumpPacket( &opkt, "writing video packet" );
"writing video packet keyframe(%d) pts(%d) dts(%d) duration(%d) "
"ipkt.duration(%d)",
opkt.flags & AV_PKT_FLAG_KEY, opkt.pts, opkt.dts, duration, ipkt->duration);
if ((opkt.data == NULL) || (opkt.size < 1)) { if ((opkt.data == NULL) || (opkt.size < 1)) {
Warning("%s:%d: Mangled AVPacket: discarding frame", __FILE__, __LINE__); Warning("%s:%d: Mangled AVPacket: discarding frame", __FILE__, __LINE__);
dumpPacket(ipkt); dumpPacket(ipkt);
@ -851,7 +836,7 @@ int VideoStore::writeVideoFramePacket(AVPacket *ipkt) {
Warning( Warning(
"%s:%d: Writing frame [av_interleaved_write_frame()] failed: %s(%d) " "%s:%d: Writing frame [av_interleaved_write_frame()] failed: %s(%d) "
" ", " ",
__FILE__, __LINE__, av_make_error_string(ret).c_str(), (ret)); __FILE__, __LINE__, av_make_error_string(ret).c_str(), ret);
dumpPacket(&safepkt); dumpPacket(&safepkt);
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
zm_dump_codecpar(video_in_stream->codecpar); zm_dump_codecpar(video_in_stream->codecpar);

View File

@ -80,7 +80,6 @@ public:
int writeVideoFramePacket( AVPacket *pkt ); int writeVideoFramePacket( AVPacket *pkt );
int writeAudioFramePacket( AVPacket *pkt ); int writeAudioFramePacket( AVPacket *pkt );
void dumpPacket( AVPacket *pkt );
}; };
#endif //havelibav #endif //havelibav

View File

@ -223,7 +223,7 @@ int main(int argc, char *argv[]) {
Info("Starting Capture version %s", ZM_VERSION); Info("Starting Capture version %s", ZM_VERSION);
static char sql[ZM_SQL_SML_BUFSIZ]; static char sql[ZM_SQL_SML_BUFSIZ];
for ( int i = 0; i < n_monitors; i ++ ) { for ( int i = 0; i < n_monitors; i ++ ) {
snprintf( sql, sizeof(sql), "UPDATE Monitors SET Status = 'Running' WHERE Id = '%d'", monitors[i]->Id() ); snprintf( sql, sizeof(sql), "REPLACE INTO Monitor_Status (Id, Status ) VALUES ('%d','Running')", monitors[i]->Id() );
if ( mysql_query( &dbconn, sql ) ) { if ( mysql_query( &dbconn, sql ) ) {
Error( "Can't run query: %s", mysql_error( &dbconn ) ); Error( "Can't run query: %s", mysql_error( &dbconn ) );
} }

View File

@ -1 +1 @@
1.31.26 1.31.28

View File

@ -55,7 +55,7 @@ $remSockFile = ZM_PATH_SOCKS.'/zms-'.sprintf('%06d',$_REQUEST['connkey']).'s.soc
$max_socket_tries = 10; $max_socket_tries = 10;
// FIXME This should not exceed web_ajax_timeout // FIXME This should not exceed web_ajax_timeout
while ( !file_exists($remSockFile) && $max_socket_tries-- ) { //sometimes we are too fast for our own good, if it hasn't been setup yet give it a second. while ( !file_exists($remSockFile) && $max_socket_tries-- ) { //sometimes we are too fast for our own good, if it hasn't been setup yet give it a second.
Logger::Debug("$remSockFile does not exist, waiting, current " . (time() - $start_time) . ' seconds' ); //Logger::Debug("$remSockFile does not exist, waiting, current " . (time() - $start_time) . ' seconds' );
usleep(200000); usleep(200000);
} }

View File

@ -171,7 +171,7 @@ class MonitorsController extends AppController {
$func = $Monitor['Function']; $func = $Monitor['Function'];
// We don't pass the request data as the monitor object because it may be a subset of the full monitor array // We don't pass the request data as the monitor object because it may be a subset of the full monitor array
$this->daemonControl( $this->Monitor->id, 'stop' ); $this->daemonControl( $this->Monitor->id, 'stop' );
if ( ( $func != 'None' ) and ( $Monitor['ServerId'] == ZM_SERVER_ID ) ) { if ( ( $func != 'None' ) and ( (!defined('ZM_SERVER_ID')) or ($Monitor['ServerId']==ZM_SERVER_ID) ) ) {
$this->daemonControl( $this->Monitor->id, 'start' ); $this->daemonControl( $this->Monitor->id, 'start' );
} }
} // end function edit } // end function edit

View File

@ -211,14 +211,16 @@ class Event {
} }
function createListThumbnail( $overwrite=false ) { function createListThumbnail( $overwrite=false ) {
if ( (!$this->SaveJPEGs()) and file_exists($this->Path().'/snapshot.jpg') ) {
$frame = null;
} else {
# Load the frame with the highest score to use as a thumbnail # Load the frame with the highest score to use as a thumbnail
if ( !($frame = dbFetchOne( 'SELECT * FROM Frames WHERE EventId=? AND Score=? ORDER BY FrameId LIMIT 1', NULL, array( $this->{'Id'}, $this->{'MaxScore'} ) )) ) { if ( !($frame = dbFetchOne( 'SELECT * FROM Frames WHERE EventId=? AND Score=? ORDER BY FrameId LIMIT 1', NULL, array( $this->{'Id'}, $this->{'MaxScore'} ) )) ) {
Error("Unable to find a Frame matching max score " . $this->{'MaxScore'} . ' for event ' . $this->{'Id'} ); Error("Unable to find a Frame matching max score " . $this->{'MaxScore'} . ' for event ' . $this->{'Id'} );
// FIXME: What if somehow the db frame was lost or score was changed? Should probably try another search for any frame. // FIXME: What if somehow the db frame was lost or score was changed? Should probably try another search for any frame.
return( false ); return( false );
} }
}
$frameId = $frame['FrameId'];
if ( ZM_WEB_LIST_THUMB_WIDTH ) { if ( ZM_WEB_LIST_THUMB_WIDTH ) {
$thumbWidth = ZM_WEB_LIST_THUMB_WIDTH; $thumbWidth = ZM_WEB_LIST_THUMB_WIDTH;
@ -259,7 +261,7 @@ class Event {
if ( ( ! $frame ) and file_exists( $eventPath.'/snapshot.jpg' ) ) { if ( ( ! $frame ) and file_exists( $eventPath.'/snapshot.jpg' ) ) {
# No frame specified, so look for a snapshot to use # No frame specified, so look for a snapshot to use
$captImage = 'snapshot.jpg'; $captImage = 'snapshot.jpg';
Debug("Frame not specified, using snapshot"); Logger::Debug("Frame not specified, using snapshot");
} else { } else {
$captImage = sprintf( '%0'.ZM_EVENT_IMAGE_DIGITS.'d-analyze.jpg', $frame['FrameId'] ); $captImage = sprintf( '%0'.ZM_EVENT_IMAGE_DIGITS.'d-analyze.jpg', $frame['FrameId'] );
if ( ! file_exists( $eventPath.'/'.$captImage ) ) { if ( ! file_exists( $eventPath.'/'.$captImage ) ) {
@ -282,7 +284,7 @@ class Event {
exec( $command, $output, $retval ); exec( $command, $output, $retval );
Logger::Debug("Retval: $retval, output: " . implode("\n", $output)); Logger::Debug("Retval: $retval, output: " . implode("\n", $output));
} else { } else {
Error("Can't create frame images from video becuase there is no video file for this event (".$Event->DefaultVideo() ); Error("Can't create frame images from video because there is no video file for event ".$Event->Id().' at ' .$Event->Path() );
} }
} // end if capture file exists } // end if capture file exists
} // end if analyze file exists } // end if analyze file exists

View File

@ -505,10 +505,17 @@ Logger::Debug("NOT Auto selecting server" . $_REQUEST['newMonitor']['ServerId'])
zmaControl( $monitor, 'stop' ); zmaControl( $monitor, 'stop' );
zmcControl( $monitor, 'stop' ); zmcControl( $monitor, 'stop' );
dbQuery( 'UPDATE Monitors SET '.implode( ', ', $changes ).' WHERE Id=?', array($mid) ); dbQuery( 'UPDATE Monitors SET '.implode( ', ', $changes ).' WHERE Id=?', array($mid) );
if ( isset($changes['Name']) ) { if ( isset($changes['Name']) or isset($changes['StorageId']) ) {
$OldStorage = new Storage( $monitor['StorageId'] );
$saferOldName = basename( $monitor['Name'] ); $saferOldName = basename( $monitor['Name'] );
if ( file_exists( $OldStorage->Path().'/'.$saferOldName ) )
unlink( $OldStorage->Path().'/'.$saferOldName );
$NewStorage = new Storage( $_REQUEST['newMonitor']['StorageId'] );
if ( ! file_exists( $NewStorage->Path().'/'.$mid ) )
mkdir( $NewStorage->Path().'/'.$mid, 0755 );
$saferNewName = basename( $_REQUEST['newMonitor']['Name'] ); $saferNewName = basename( $_REQUEST['newMonitor']['Name'] );
rename( ZM_DIR_EVENTS.'/'.$saferOldName, ZM_DIR_EVENTS.'/'.$saferNewName); symlink( $mid, $NewStorage->Path().'/'.$saferNewName );
} }
if ( isset($changes['Width']) || isset($changes['Height']) ) { if ( isset($changes['Width']) || isset($changes['Height']) ) {
$newW = $_REQUEST['newMonitor']['Width']; $newW = $_REQUEST['newMonitor']['Width'];
@ -553,9 +560,10 @@ Logger::Debug("NOT Auto selecting server" . $_REQUEST['newMonitor']['ServerId'])
$zoneArea = $_REQUEST['newMonitor']['Width'] * $_REQUEST['newMonitor']['Height']; $zoneArea = $_REQUEST['newMonitor']['Width'] * $_REQUEST['newMonitor']['Height'];
dbQuery( "insert into Zones set MonitorId = ?, Name = 'All', Type = 'Active', Units = 'Percent', NumCoords = 4, Coords = ?, Area=?, AlarmRGB = 0xff0000, CheckMethod = 'Blobs', MinPixelThreshold = 25, MinAlarmPixels=?, MaxAlarmPixels=?, FilterX = 3, FilterY = 3, MinFilterPixels=?, MaxFilterPixels=?, MinBlobPixels=?, MinBlobs = 1", array( $mid, sprintf( "%d,%d %d,%d %d,%d %d,%d", 0, 0, $_REQUEST['newMonitor']['Width']-1, 0, $_REQUEST['newMonitor']['Width']-1, $_REQUEST['newMonitor']['Height']-1, 0, $_REQUEST['newMonitor']['Height']-1 ), $zoneArea, intval(($zoneArea*3)/100), intval(($zoneArea*75)/100), intval(($zoneArea*3)/100), intval(($zoneArea*75)/100), intval(($zoneArea*2)/100) ) ); dbQuery( "insert into Zones set MonitorId = ?, Name = 'All', Type = 'Active', Units = 'Percent', NumCoords = 4, Coords = ?, Area=?, AlarmRGB = 0xff0000, CheckMethod = 'Blobs', MinPixelThreshold = 25, MinAlarmPixels=?, MaxAlarmPixels=?, FilterX = 3, FilterY = 3, MinFilterPixels=?, MaxFilterPixels=?, MinBlobPixels=?, MinBlobs = 1", array( $mid, sprintf( "%d,%d %d,%d %d,%d %d,%d", 0, 0, $_REQUEST['newMonitor']['Width']-1, 0, $_REQUEST['newMonitor']['Width']-1, $_REQUEST['newMonitor']['Height']-1, 0, $_REQUEST['newMonitor']['Height']-1 ), $zoneArea, intval(($zoneArea*3)/100), intval(($zoneArea*75)/100), intval(($zoneArea*3)/100), intval(($zoneArea*75)/100), intval(($zoneArea*2)/100) ) );
//$view = 'none'; //$view = 'none';
mkdir( ZM_DIR_EVENTS.'/'.$mid, 0755 ); $Storage = new Storage( $_REQUEST['newMonitor']['StorageId'] );
mkdir( $Storage->Path().'/'.$mid, 0755 );
$saferName = basename($_REQUEST['newMonitor']['Name']); $saferName = basename($_REQUEST['newMonitor']['Name']);
symlink( $mid, ZM_DIR_EVENTS.'/'.$saferName ); symlink( $mid, $Storage->Path().'/'.$saferName );
if ( isset($_COOKIE['zmGroup']) ) { if ( isset($_COOKIE['zmGroup']) ) {
dbQuery( 'INSERT INTO Groups_Monitors (GroupId,MonitorId) VALUES (?,?)', array($_COOKIE['zmGroup'],$mid) ); dbQuery( 'INSERT INTO Groups_Monitors (GroupId,MonitorId) VALUES (?,?)', array($_COOKIE['zmGroup'],$mid) );
} }

View File

@ -165,7 +165,7 @@ function generateAuthHash( $useRemoteAddr ) {
$backTrace = debug_backtrace(); $backTrace = debug_backtrace();
$file = $backTrace[1]['file']; $file = $backTrace[1]['file'];
$line = $backTrace[1]['line']; $line = $backTrace[1]['line'];
Warning("Session is not active. AuthHash will not be cached. called from $file:$line"); Warning("Session is not active. AuthHash will not be cached. called from $file:$line. OldHash:" . $_SESSION['AuthHash'] . ' generated at ' . $_SESSION['AuthHashGeneratedAt'] . ' < ' . $time . ' - ( ' . ZM_AUTH_HASH_TTL . '* 1800 = ' . ZM_AUTH_HASH_TTL * 1800 );
} }
$_SESSION['AuthHash'] = $auth; $_SESSION['AuthHash'] = $auth;
$_SESSION['AuthHashGeneratedAt'] = $time; $_SESSION['AuthHashGeneratedAt'] = $time;
@ -1236,30 +1236,37 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&amp;' ) {
case 'ServerId': case 'ServerId':
if ( $value == 'ZM_SERVER_ID' ) { if ( $value == 'ZM_SERVER_ID' ) {
$value = ZM_SERVER_ID; $value = ZM_SERVER_ID;
} else if ( $value == 'NULL' ) {
} else { } else {
$value = dbEscape($value); $value = dbEscape($value);
} }
break; break;
case 'StorageId': case 'StorageId':
$StorageArea = new Storage( $value ); $StorageArea = new Storage( $value );
if ( $value != 'NULL' )
$value = dbEscape($value); $value = dbEscape($value);
break; break;
case 'DateTime': case 'DateTime':
case 'StartDateTime': case 'StartDateTime':
case 'EndDateTime': case 'EndDateTime':
if ( $value != 'NULL' )
$value = "'".strftime( STRF_FMT_DATETIME_DB, strtotime( $value ) )."'"; $value = "'".strftime( STRF_FMT_DATETIME_DB, strtotime( $value ) )."'";
break; break;
case 'Date': case 'Date':
case 'StartDate': case 'StartDate':
case 'EndDate': case 'EndDate':
if ( $value != 'NULL' )
$value = "to_days( '".strftime( STRF_FMT_DATETIME_DB, strtotime( $value ) )."' )"; $value = "to_days( '".strftime( STRF_FMT_DATETIME_DB, strtotime( $value ) )."' )";
break; break;
case 'Time': case 'Time':
case 'StartTime': case 'StartTime':
case 'EndTime': case 'EndTime':
if ( $value != 'NULL' )
$value = "extract( hour_second from '".strftime( STRF_FMT_DATETIME_DB, strtotime( $value ) )."' )"; $value = "extract( hour_second from '".strftime( STRF_FMT_DATETIME_DB, strtotime( $value ) )."' )";
break; break;
default : default :
if ( $value != 'NULL' )
$value = dbEscape($value); $value = dbEscape($value);
break; break;
} }

View File

@ -203,7 +203,7 @@ if ( ZM_ENABLE_CSRF_MAGIC && $action != 'login' && $view != 'view_video' && $vie
require_once( 'includes/actions.php' ); require_once( 'includes/actions.php' );
# If I put this here, it protects all views and popups, but it has to go after actions.php because actions.php does the actual logging in. # If I put this here, it protects all views and popups, but it has to go after actions.php because actions.php does the actual logging in.
if ( ZM_OPT_USE_AUTH && ! isset($user) ) { if ( ZM_OPT_USE_AUTH and ! isset($user) ) {
Logger::Debug("Redirecting to login" ); Logger::Debug("Redirecting to login" );
$view = 'login'; $view = 'login';
$request = null; $request = null;

View File

@ -1,7 +1,7 @@
.ptzControls { .ptzControls {
vertical-align: top; vertical-align: top;
margin: 10px auto 0; margin: 10px auto 0;
width: 500px; width: 520px;
} }
.ptzControls::after { .ptzControls::after {

View File

@ -71,7 +71,9 @@ html ul.tabs li.active, html ul.tabs li.active a:hover {
} }
--> -->
</style> </style>
<script type="text/javascript" src="<?php echo ZM_SKIN_PATH; ?>/js/jquery.js"></script> <script type="text/javascript">
<?php include(ZM_SKIN_PATH.'/js/jquery.js'
</script>
<script type="text/javascript" language="javascript" charset="utf-8"> <script type="text/javascript" language="javascript" charset="utf-8">
/*==========[tab code]==========*/ /*==========[tab code]==========*/
@ -579,12 +581,7 @@ else if (document.layers) window.onload=start_slider;
return( ob_get_clean() ); return( ob_get_clean() );
} }
function exportEventImagesMaster( $eids ) {
function exportEventImagesMaster( $eids )
{
ob_start(); ob_start();
exportHeader( translate('Images').' Master' ); exportHeader( translate('Images').' Master' );
?> ?>
@ -611,32 +608,27 @@ function exportEventImagesMaster( $eids )
//trigger_error(print_r($monitorNames,1)); //trigger_error(print_r($monitorNames,1));
?> ?>
<div id= 'tabs'> <div id="tabs">
<ul class= 'tabs'> <ul class="tabs">
<li class = 'active' ><a href='#all' > All </a></li> <li class="active"><a href="#all"> All </a></li>
<?php <?php
foreach ($monitors as $monitor) { foreach ($monitors as $monitor) {
# code... # code...
echo "<li><a href='#tab$monitor'>" . $monitorNames[$monitor] . "</a></li>"; echo "<li><a href='#tab$monitor'>" . $monitorNames[$monitor] . '</a></li>';
} }
?> ?>
</ul> </ul>
</div> </div>
<table width="100%" height="100%" ><tr> <table width="100%" height="100%" ><tr>
<td valign="top" bgcolor="#dddddd" style="padding:10px;"> <td valign="top" bgcolor="#dddddd" style="padding:10px;">
<div class='tab_content' id='all'> <div class='tab_content' id='all'>
<h2> All </h2> <h2> All </h2>
<?php <?php
if (!is_array($eids)) if (!is_array($eids)) {
{
echo "<div><a href=\"javascript:switchevent('$eids/zm/EventImages.html');\"> $eids </div>"; echo "<div><a href=\"javascript:switchevent('$eids/zm/EventImages.html');\"> $eids </div>";
} }
?> ?>
<?php foreach($eids as $eid) <?php foreach($eids as $eid) {
{
?> ?>
<div><a href="javascript:switchevent('<?php echo $eventPath[$eid]; ?>/zmEventImages.html');"><?php echo$eid?></a></div> <div><a href="javascript:switchevent('<?php echo $eventPath[$eid]; ?>/zmEventImages.html');"><?php echo$eid?></a></div>
<?php <?php
@ -644,15 +636,11 @@ function exportEventImagesMaster( $eids )
?> ?>
</div> </div>
<?php <?php
foreach ($monitors as $monitor) {
foreach ($monitors as $monitor)
{
echo "<div class='tab_content' id='tab$monitor'>"; echo "<div class='tab_content' id='tab$monitor'>";
echo "<h2>Monitor: " . $monitorNames[$monitor] . " </h2>"; echo "<h2>Monitor: " . $monitorNames[$monitor] . " </h2>";
foreach ($eids as $eid) foreach ($eids as $eid) {
{ if ($eventMonitorId[$eid] == $monitor) {
if ($eventMonitorId[$eid] == $monitor)
{
?> ?>
<div><a href="javascript:switchevent('<?php echo $eventPath[$eid]; ?>/zmEventImages.html');"><?php echo$eid?></a></div> <div><a href="javascript:switchevent('<?php echo $eventPath[$eid]; ?>/zmEventImages.html');"><?php echo$eid?></a></div>
<?php <?php
@ -660,7 +648,6 @@ function exportEventImagesMaster( $eids )
} }
echo'</div>'; echo'</div>';
} }
?> ?>
</td><td> </td><td>
@ -750,20 +737,18 @@ function loadintoIframe(iframeid, url){
function exportFileList( $eid, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc ) function exportFileList( $eid, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc ) {
{
if ( (!canView('Events')) or ! $eid ) {
return;
}
if ( canView( 'Events' ) && $eid )
{
$event = new Event($eid); $event = new Event($eid);
$eventPath = $event->Path(); $eventPath = $event->Path();
$files = array(); $files = array();
if ( $dir = opendir( $eventPath ) ) if ( $dir = opendir($eventPath) ) {
{ while ( ($file = readdir($dir)) !== false ) {
while ( ($file = readdir( $dir )) !== false ) if ( is_file($eventPath.'/'.$file) ) {
{
if ( is_file( $eventPath."/".$file ) )
{
$files[$file] = $file; $files[$file] = $file;
} }
} }
@ -772,140 +757,111 @@ function exportFileList( $eid, $exportDetail, $exportFrames, $exportImages, $exp
$exportFileList = array(); $exportFileList = array();
if ( $exportDetail ) if ( $exportDetail ) {
{ $file = 'zmEventDetail.html';
$file = "zmEventDetail.html"; if ( !($fp = fopen( $eventPath.'/'.$file, 'w' )) ) {
if ( !($fp = fopen( $eventPath."/".$file, "w" )) )
{
Fatal( "Can't open event detail export file '$file'" ); Fatal( "Can't open event detail export file '$file'" );
} }
fwrite( $fp, exportEventDetail( $event, $exportFrames, $exportImages ) ); fwrite( $fp, exportEventDetail( $event, $exportFrames, $exportImages ) );
fclose( $fp ); fclose( $fp );
$exportFileList[$file] = $eventPath."/".$file; $exportFileList[$file] = $eventPath."/".$file;
} }
if ( $exportFrames ) if ( $exportFrames ) {
{ $file = 'zmEventFrames.html';
$file = "zmEventFrames.html"; if ( !($fp = fopen( $eventPath.'/'.$file, 'w' )) ) {
if ( !($fp = fopen( $eventPath."/".$file, "w" )) )
{
Fatal( "Can't open event frames export file '$file'" ); Fatal( "Can't open event frames export file '$file'" );
} }
fwrite( $fp, exportEventFrames( $event, $exportDetail, $exportImages ) ); fwrite( $fp, exportEventFrames( $event, $exportDetail, $exportImages ) );
fclose( $fp ); fclose( $fp );
$exportFileList[$file] = $eventPath."/".$file; $exportFileList[$file] = $eventPath."/".$file;
} }
if ( $exportImages ) if ( $exportImages ) {
{
$filesLeft = array(); $filesLeft = array();
$myfilelist = array(); $myfilelist = array();
foreach ( $files as $file ) foreach ( $files as $file ) {
{ if ( preg_match( '/-(?:capture|analyse).jpg$/', $file ) ) {
if ( preg_match( "/-(?:capture|analyse).jpg$/", $file ) )
{
$exportFileList[$file] = $eventPath."/".$file; $exportFileList[$file] = $eventPath."/".$file;
$myfilelist[$file] = $eventPath."/".$file; $myfilelist[$file] = $eventPath."/".$file;
} } else {
else
{
$filesLeft[$file] = $file; $filesLeft[$file] = $file;
} }
} }
$files = $filesLeft; $files = $filesLeft;
// create an image slider // create an image slider
if ( !empty($myfilelist) ) { if ( !empty($myfilelist) ) {
$file = "zmEventImages.html"; $file = 'zmEventImages.html';
if ( !($fp = fopen( $eventPath."/".$file, "w" )) ) Fatal( "Can't open event images export file '$file'" ); if ( !($fp = fopen($eventPath.'/'.$file, 'w')) ) Fatal( "Can't open event images export file '$file'" );
fwrite( $fp, exportEventImages( $event, $exportDetail, $exportFrames, $myfilelist ) ); fwrite( $fp, exportEventImages( $event, $exportDetail, $exportFrames, $myfilelist ) );
fclose( $fp ); fclose( $fp );
$exportFileList[$file] = $eventPath."/".$file; $exportFileList[$file] = $eventPath."/".$file;
} }
} # end if exportImages
if ( $exportVideo ) {
}
if ( $exportVideo )
{
$filesLeft = array(); $filesLeft = array();
foreach ( $files as $file ) foreach ( $files as $file ) {
{ if ( preg_match( '/\.(?:mpg|mpeg|mp4|mkv|avi|asf|3gp)$/', $file ) ) {
if ( preg_match( "/\.(?:mpg|mpeg|mp4|avi|asf|3gp)$/", $file ) ) $exportFileList[$file] = $eventPath.'/'.$file;
{ } else {
$exportFileList[$file] = $eventPath."/".$file;
}
else
{
$filesLeft[$file] = $file; $filesLeft[$file] = $file;
} }
} }
$files = $filesLeft; $files = $filesLeft;
} } # end if exportVideo
if ( $exportMisc )
{ if ( $exportMisc ) {
foreach ( $files as $file ) foreach ( $files as $file ) {
{ $exportFileList[$file] = $eventPath.'/'.$file;
$exportFileList[$file] = $eventPath."/".$file;
} }
$files = array(); $files = array();
} }
}
return( array_values( $exportFileList ) ); return( array_values( $exportFileList ) );
} }
function exportEvents( $eids, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc, $exportFormat, $exportStructure = false ) function exportEvents( $eids, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc, $exportFormat, $exportStructure = false ) {
{
if ( canView( 'Events' ) && !empty($eids) ) if ( (!canView('Events')) || empty($eids) ) {
{ return false;
$export_root = "zmExport"; }
$export_listFile = "zmFileList.txt"; $export_root = 'zmExport';
$export_listFile = 'zmFileList.txt';
$exportFileList = array(); $exportFileList = array();
$html_eventMaster = ''; $html_eventMaster = '';
if ( is_array( $eids ) ) if ( is_array($eids) ) {
{ foreach ( $eids as $eid ) {
foreach ( $eids as $eid )
{
$exportFileList = array_merge( $exportFileList, exportFileList( $eid , $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc ) ); $exportFileList = array_merge( $exportFileList, exportFileList( $eid , $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc ) );
} }
} else {
}
else
{
$eid = $eids; $eid = $eids;
$exportFileList = exportFileList( $eid, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc ); $exportFileList = exportFileList( $eid, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc );
} }
// create an master image slider // create an master image slider
if($exportImages) if ( $exportImages ) {
{ if ( !is_array($eids) ) {
if ( !is_array($eids) )
{
$eids = array($eids); $eids = array($eids);
} }
$monitorPath = ZM_DIR_EVENTS."/"; $monitorPath = ZM_DIR_EVENTS.'/';
$html_eventMaster = 'zmEventImagesMaster_'.date('Ymd_His'). '.html'; $html_eventMaster = 'zmEventImagesMaster_'.date('Ymd_His'). '.html';
if ( !($fp = fopen( $monitorPath."/".$html_eventMaster, "w" )) ) Fatal( "Can't open event images export file '$html_eventMaster'" ); if ( !($fp = fopen( $monitorPath.'/'.$html_eventMaster, 'w' )) ) Fatal( "Can't open event images export file '$html_eventMaster'" );
fwrite($fp, exportEventImagesMaster($eids)); fwrite($fp, exportEventImagesMaster($eids));
fclose($fp); fclose($fp);
$exportFileList[] = $monitorPath."/".$html_eventMaster; $exportFileList[] = $monitorPath.'/'.$html_eventMaster;
} }
$listFile = ZM_DIR_EXPORTS."/".$export_listFile; $listFile = ZM_DIR_EXPORTS.'/'.$export_listFile;
if ( !($fp = fopen( $listFile, "w" )) ) if ( !($fp = fopen($listFile, 'w')) ) {
{
Fatal( "Can't open event export list file '$listFile'" ); Fatal( "Can't open event export list file '$listFile'" );
} }
foreach ( $exportFileList as $exportFile ) foreach ( $exportFileList as $exportFile ) {
{
fwrite( $fp, "$exportFile\n" ); fwrite( $fp, "$exportFile\n" );
} }
fclose( $fp ); fclose( $fp );
$archive = ""; $archive = '';
if ( $exportFormat == "tar" ) if ( $exportFormat == 'tar' ) {
{ $archive = ZM_DIR_EXPORTS.'/'.$export_root.'.tar.gz';
$archive = ZM_DIR_EXPORTS."/".$export_root.".tar.gz";
@unlink( $archive ); @unlink( $archive );
if ( $exportStructure == 'flat' ) { //strip file paths if we choose if ( $exportStructure == 'flat' ) { //strip file paths if we choose
$command = "nice -10 tar --create --gzip --file=".escapeshellarg($archive)." --files-from=".escapeshellarg($listFile)." --xform='s#^.+/##x'"; $command = "nice -10 tar --create --gzip --file=".escapeshellarg($archive)." --files-from=".escapeshellarg($listFile)." --xform='s#^.+/##x'";
@ -913,17 +869,14 @@ function exportEvents( $eids, $exportDetail, $exportFrames, $exportImages, $expo
$command = "nice -10 tar --create --gzip --file=".escapeshellarg($archive)." --files-from=".escapeshellarg($listFile); $command = "nice -10 tar --create --gzip --file=".escapeshellarg($archive)." --files-from=".escapeshellarg($listFile);
} }
exec( $command, $output, $status ); exec( $command, $output, $status );
if ( $status ) if ( $status ) {
{
Error( "Command '$command' returned with status $status" ); Error( "Command '$command' returned with status $status" );
if ( $output[0] ) if ( $output[0] )
Error( "First line of output is '".$output[0]."'" ); Error( "First line of output is '".$output[0]."'" );
return( false ); return( false );
} }
} } elseif ( $exportFormat == 'zip' ) {
elseif ( $exportFormat == "zip" ) $archive = ZM_DIR_EXPORTS.'/'.$export_root.'.zip';
{
$archive = ZM_DIR_EXPORTS."/".$export_root.".zip";
@unlink( $archive ); @unlink( $archive );
if ($exportStructure == 'flat') { if ($exportStructure == 'flat') {
$command = "cat ".escapeshellarg($listFile)." | nice -10 zip -q -j ".escapeshellarg($archive)." -@"; $command = "cat ".escapeshellarg($listFile)." | nice -10 zip -q -j ".escapeshellarg($archive)." -@";
@ -934,12 +887,11 @@ function exportEvents( $eids, $exportDetail, $exportFrames, $exportImages, $expo
//-bash: zip: command not found //-bash: zip: command not found
exec( $command, $output, $status ); exec( $command, $output, $status );
if ( $status ) if ( $status ) {
{
Error("Command '$command' returned with status $status"); Error("Command '$command' returned with status $status");
if ( $output[0] ) if ( $output[0] )
Error("First line of output is '".$output[0]."'"); Error("First line of output is '".$output[0]."'");
return( false ); return false;
} }
} }
@ -948,6 +900,5 @@ function exportEvents( $eids, $exportDetail, $exportFrames, $exportImages, $expo
unlink($monitorPath.'/'.$html_eventMaster); unlink($monitorPath.'/'.$html_eventMaster);
} }
}
return( '?view=archive%26type='.$exportFormat ); return( '?view=archive%26type='.$exportFormat );
} }

View File

@ -46,6 +46,9 @@ foreach ( $storage_areas as $S ) {
?> ?>
<div class="controlHeader"> <div class="controlHeader">
<input type="hidden" name="filtering" value="" /> <input type="hidden" name="filtering" value="" />
<?php
$groupSql = '';
if ( Group::find_all() ) { ?>
<span id="groupControl"><label><?php echo translate('Group') ?>:</label> <span id="groupControl"><label><?php echo translate('Group') ?>:</label>
<?php <?php
# This will end up with the group_id of the deepest selection # This will end up with the group_id of the deepest selection
@ -54,6 +57,7 @@ echo Group::get_group_dropdown();
$groupSql = Group::get_group_sql( $group_id ); $groupSql = Group::get_group_sql( $group_id );
?> ?>
</span> </span>
<?php } ?>
<span id="monitorControl"><label><?php echo translate('Monitor') ?>:</label> <span id="monitorControl"><label><?php echo translate('Monitor') ?>:</label>
<?php <?php
@ -85,7 +89,7 @@ if ( ! is_array( $selected_monitor_ids ) ) {
$values += $ids; $values += $ids;
} }
$sql = 'SELECT * FROM Monitors' . ( count($conditions) ? ' WHERE ' . implode(' AND ', $conditions ) : '' ).' ORDER BY Sequence ASC'; $sql = 'SELECT *,S.Status AS Status, S.CaptureFPS AS CaptureFPS FROM Monitors AS M LEFT JOIN Monitor_Status AS S ON S.Id=M.Id ' . ( count($conditions) ? ' WHERE ' . implode(' AND ', $conditions ) : '' ).' ORDER BY Sequence ASC';
$monitors = dbFetchAll( $sql, null, $values ); $monitors = dbFetchAll( $sql, null, $values );
$displayMonitors = array(); $displayMonitors = array();
$monitors_dropdown = array(); $monitors_dropdown = array();

View File

@ -215,7 +215,18 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
<td class="colName"><a <?php echo (canView('Stream') && $monitor['Function'] != 'None' ? 'href="?view=watch&amp;mid='.$monitor['Id'].'">' : '>') . $monitor['Name'] ?></a></td> <td class="colName"><a <?php echo (canView('Stream') && $monitor['Function'] != 'None' ? 'href="?view=watch&amp;mid='.$monitor['Id'].'">' : '>') . $monitor['Name'] ?></a></td>
<td class="colFunction"> <td class="colFunction">
<?php echo makePopupLink( '?view=function&amp;mid='.$monitor['Id'], 'zmFunction', 'function', '<span class="'.$fclass.'">'.translate('Fn'.$monitor['Function']).( empty($monitor['Enabled']) ? ', disabled' : '' ) .'</span>', canEdit( 'Monitors' ) ) ?><br/> <?php echo makePopupLink( '?view=function&amp;mid='.$monitor['Id'], 'zmFunction', 'function', '<span class="'.$fclass.'">'.translate('Fn'.$monitor['Function']).( empty($monitor['Enabled']) ? ', disabled' : '' ) .'</span>', canEdit( 'Monitors' ) ) ?><br/>
<?php echo $monitor['CaptureFPS'] . ( ( $monitor['Function'] == 'Mocord' or $monitor['Function'] == 'Modect' ) ? ' / ' . $monitor['AnalysisFPS'] : '' ) . ' FPS' ?> <?php
$fps_string = '';
if ( isset($monitor['CaptureFPS']) ) {
$fps_string .= $monitor['CaptureFPS'];
}
if ( isset($monitor['AnalysisFPS']) and ( $monitor['Function'] == 'Mocord' or $monitor['Function'] == 'Modect' ) ) {
$fps_string .= ' / ' . $monitor['AnalysisFPS'];
}
if ($fps_string) $fps_string .= ' FPS';
echo $fps_string;
?>
</td> </td>
<?php <?php
if ( count($servers) ) { ?> if ( count($servers) ) { ?>

View File

@ -25,7 +25,6 @@ if ( !canView( 'Events' ) || (!empty($_REQUEST['execute']) && !canEdit('Events')
require_once( 'includes/Event.php' ); require_once( 'includes/Event.php' );
$countSql = 'SELECT count(E.Id) AS EventCount FROM Monitors AS M INNER JOIN Events AS E ON (M.Id = E.MonitorId) WHERE'; $countSql = 'SELECT count(E.Id) AS EventCount FROM Monitors AS M INNER JOIN Events AS E ON (M.Id = E.MonitorId) WHERE';
$eventsSql = 'SELECT E.*,M.Name AS MonitorName,M.DefaultScale FROM Monitors AS M INNER JOIN Events AS E on (M.Id = E.MonitorId) WHERE'; $eventsSql = 'SELECT E.*,M.Name AS MonitorName,M.DefaultScale FROM Monitors AS M INNER JOIN Events AS E on (M.Id = E.MonitorId) WHERE';
if ( $user['MonitorIds'] ) { if ( $user['MonitorIds'] ) {
@ -57,10 +56,8 @@ else
$limit = 0; $limit = 0;
$nEvents = dbFetchOne( $countSql, 'EventCount' ); $nEvents = dbFetchOne( $countSql, 'EventCount' );
Warning("Number of events: $nEvents");
if ( !empty($limit) && $nEvents > $limit ) { if ( !empty($limit) && $nEvents > $limit ) {
$nEvents = $limit; $nEvents = $limit;
Logger::Debug("Number of events: $nEvents");
} }
$pages = (int)ceil($nEvents/ZM_WEB_EVENTS_PER_PAGE); $pages = (int)ceil($nEvents/ZM_WEB_EVENTS_PER_PAGE);
if ( !empty($page) ) { if ( !empty($page) ) {
@ -68,9 +65,7 @@ if ( !empty($page) ) {
$page = 1; $page = 1;
else if ( $page > $pages ) else if ( $page > $pages )
$page = $pages; $page = $pages;
}
if ( !empty($page) ) {
$limitStart = (($page-1)*ZM_WEB_EVENTS_PER_PAGE); $limitStart = (($page-1)*ZM_WEB_EVENTS_PER_PAGE);
if ( empty( $limit ) ) { if ( empty( $limit ) ) {
$limitAmount = ZM_WEB_EVENTS_PER_PAGE; $limitAmount = ZM_WEB_EVENTS_PER_PAGE;
@ -210,8 +205,8 @@ while ( $event_row = dbFetchNext( $results ) ) {
?> ?>
<td class="colThumbnail"> <td class="colThumbnail">
<?php <?php
if ( ( $event->SaveJPEGs() == 4 ) and file_exists($event->Path().'/snapshot.jpg') ) { if ( ( $event->SaveJPEGs() == 0 ) and file_exists($event->Path().'/snapshot.jpg') ) {
Logger::Debug("Using snapshot"); Logger::Debug("Using snapshot" . $event->Path().'/snapshot.jpg' );
$imgSrc = '?view=image&amp;eid='.$event->Id().'&amp;fid=snapshot&amp;width='.$thumbData['Width'].'&amp;height='.$thumbData['Height']; $imgSrc = '?view=image&amp;eid='.$event->Id().'&amp;fid=snapshot&amp;width='.$thumbData['Width'].'&amp;height='.$thumbData['Height'];
} else { } else {
Logger::Debug("Not Using snapshot" . $event->Path().'/snapshot.jpg' ); Logger::Debug("Not Using snapshot" . $event->Path().'/snapshot.jpg' );
@ -220,17 +215,12 @@ while ( $event_row = dbFetchNext( $results ) ) {
$streamSrc = $event->getStreamSrc( array( 'mode'=>'jpeg', 'scale'=>$scale, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'replay'=>'single') ); $streamSrc = $event->getStreamSrc( array( 'mode'=>'jpeg', 'scale'=>$scale, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'replay'=>'single') );
$imgHtml = '<img id="thumbnail'.$event->id().'" src="'.$imgSrc.'" alt="'. validHtmlStr('Event '.$event->Id()) .'" style="width:'. validInt($thumbData['Width']) .'px;height:'. validInt($thumbData['Height']).'px;" onmouseover="this.src=\''.$streamSrc.'\';" onmouseout="this.src=\''.$imgSrc.'\';"/>'; $imgHtml = '<img id="thumbnail'.$event->id().'" src="'.$imgSrc.'" alt="'. validHtmlStr('Event '.$event->Id()) .'" style="width:'. validInt($thumbData['Width']) .'px;height:'. validInt($thumbData['Height']).'px;" onmouseover="this.src=\''.$streamSrc.'\';" onmouseout="this.src=\''.$imgSrc.'\';"/>';
echo '<a href="?view=event&amp;eid='. $event->Id().$filterQuery.$sortQuery.'&amp;page=1">'.$imgHtml.'</a>';
echo makePopupLink(
'?view=frame&amp;eid='.$event->Id().'&amp;fid='.$thumbData['FrameId'],
'zmImage',
array( 'image', reScale( $event->Width(), $scale ), reScale( $event->Height(), $scale ) ),
$imgHtml
);
?> ?>
</td> </td>
<?php <?php
} else { } else {
Logger::Debug("No thumbnail data");
?> ?>
<td class="colThumbnail">&nbsp;</td> <td class="colThumbnail">&nbsp;</td>
<?php <?php
@ -255,7 +245,7 @@ while ( $event_row = dbFetchNext( $results ) ) {
?><td></td> ?><td></td>
<?php <?php
} }
?> ?><td></td>
</tr> </tr>
</tfoot> </tfoot>
<?php <?php

View File

@ -101,24 +101,20 @@ elseif ( !empty($_REQUEST['eids']) )
</tr> </tr>
</tbody> </tbody>
</table> </table>
<input type="button" id="exportButton" name="exportButton" value="<?php echo translate('Export') ?>" onclick="exportEvent( this.form );" disabled="disabled"/> <button id="exportButton" name="exportButton" value="Export" onclick="exportEvent(this.form);" disabled="disabled"><?php echo translate('Export') ?></button>
</form> </form>
</div> </div>
<?php <?php
if ( isset($_REQUEST['generated']) ) if ( isset($_REQUEST['generated']) ) {
{
?> ?>
<h2 id="exportProgress" class="<?php echo $_REQUEST['generated']?'infoText':'errorText' ?>"><span id="exportProgressText"><?php echo $_REQUEST['generated']?translate('ExportSucceeded'):translate('ExportFailed') ?></span><span id="exportProgressTicker"></span></h2> <h2 id="exportProgress" class="<?php echo $_REQUEST['generated']?'infoText':'errorText' ?>"><span id="exportProgressText"><?php echo $_REQUEST['generated']?translate('ExportSucceeded'):translate('ExportFailed') ?></span><span id="exportProgressTicker"></span></h2>
<?php <?php
} } else {
else
{
?> ?>
<h2 id="exportProgress" class="hidden warnText"><span id="exportProgressText"><?php echo translate('Exporting') ?></span><span id="exportProgressTicker"></span></h2> <h2 id="exportProgress" class="hidden warnText"><span id="exportProgressText"><?php echo translate('Exporting') ?></span><span id="exportProgressTicker"></span></h2>
<?php <?php
} }
if ( !empty($_REQUEST['generated']) ) if ( !empty($_REQUEST['generated']) ) {
{
?> ?>
<h3 id="downloadLink"><a href="<?php echo validHtmlStr($_REQUEST['exportFile']) ?>"><?php echo translate('Download') ?></a></h3> <h3 id="downloadLink"><a href="<?php echo validHtmlStr($_REQUEST['exportFile']) ?>"><?php echo translate('Download') ?></a></h3>
<?php <?php

View File

@ -334,7 +334,7 @@ echo htmlSelect( 'filter[Query][sort_asc]', $sort_dirns, $filter->sort_asc() );
</td> </td>
<td> <td>
<label for="filter[Query][limit]"><?php echo translate('LimitResultsPre') ?></label> <label for="filter[Query][limit]"><?php echo translate('LimitResultsPre') ?></label>
<input type="text" id="filter[Query][limit]" name="filter[Query][limit]" value="<?php echo (null !== $filter->limit())?validInt($filter->limit()):'' ?>"/><?php echo translate('LimitResultsPost') ?> <input type="number" id="filter[Query][limit]" name="filter[Query][limit]" value="<?php echo (null !== $filter->limit())?validInt($filter->limit()):'' ?>"/><?php echo translate('LimitResultsPost') ?>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View File

@ -16,6 +16,11 @@ function validateForm ( form ) {
alert( errorBrackets ); alert( errorBrackets );
return false; return false;
} }
var numbers_reg = /\D/;
if ( numbers_reg.test( form.elements['filter[Query][limit]'].value ) ) {
alert( "There appear to be non-numeric characters in your limit. Limit must be a positive integer value or empty." );
return false;
}
return true; return true;
} }

View File

@ -34,17 +34,16 @@ controlOptions[<?php echo $row['Id'] ?>][<?php echo $i ?>] = '<?php echo transla
} }
?> ?>
<?php
if ( empty($_REQUEST['mid']) ) {
?>
var monitorNames = new Object(); var monitorNames = new Object();
<?php <?php
foreach ( dbFetchAll( "select Name from Monitors order by Name asc", "Name" ) as $name ) { $query = empty($_REQUEST['mid']) ? dbQuery('SELECT Name FROM Monitors') : dbQuery('SELECT Name FROM Monitors WHERE Id != ?', array($_REQUEST['mid']) );
if ( $query ) {
while ( $name = dbFetchNext($query, 'Name') ) {
?> ?>
monitorNames['<?php echo validJsStr($name) ?>'] = true; monitorNames['<?php echo validJsStr($name) ?>'] = true;
<?php <?php
} } // end foreach
} } # end if query
?> ?>
function validateForm( form ) { function validateForm( form ) {
@ -52,7 +51,7 @@ function validateForm( form ) {
if ( form.elements['newMonitor[Name]'].value.search( /[^\w\-\.\(\)\:\/ ]/ ) >= 0 ) if ( form.elements['newMonitor[Name]'].value.search( /[^\w\-\.\(\)\:\/ ]/ ) >= 0 )
errors[errors.length] = "<?php echo translate('BadNameChars') ?>"; errors[errors.length] = "<?php echo translate('BadNameChars') ?>";
else if ( form.elements.mid.value == 0 && monitorNames[form.elements['newMonitor[Name]'].value] ) else if ( monitorNames[form.elements['newMonitor[Name]'].value] )
errors[errors.length] = "<?php echo translate('DuplicateMonitorName') ?>"; errors[errors.length] = "<?php echo translate('DuplicateMonitorName') ?>";
if ( form.elements['newMonitor[AnalysisFPSLimit]'].value && !(parseFloat(form.elements['newMonitor[AnalysisFPSLimit]'].value) > 0 ) ) if ( form.elements['newMonitor[AnalysisFPSLimit]'].value && !(parseFloat(form.elements['newMonitor[AnalysisFPSLimit]'].value) > 0 ) )

View File

@ -35,6 +35,7 @@ if ( $_REQUEST['id'] ) {
$newStorage['Path'] = ''; $newStorage['Path'] = '';
$newStorage['Type'] = 'local'; $newStorage['Type'] = 'local';
$newStorage['Scheme'] = 'Medium'; $newStorage['Scheme'] = 'Medium';
$newStorage['StorageId'] = '';
} }
$type_options = array( 'local' => translate('Local'), 's3fs' => translate('s3fs') ); $type_options = array( 'local' => translate('Local'), 's3fs' => translate('s3fs') );

View File

@ -18,9 +18,8 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
// //
if ( !canView( 'Events' ) ) if ( !canView( 'Events' ) ) {
{ $view = 'error';
$view = "error";
return; return;
} }
@ -28,13 +27,13 @@ $archivetype = $_REQUEST['type'];
if ( $archivetype ) { if ( $archivetype ) {
switch ($archivetype) { switch ($archivetype) {
case "tar": case 'tar':
$mimetype = "gzip"; $mimetype = 'gzip';
$file_ext = "tar.gz"; $file_ext = 'tar.gz';
break; break;
case "zip": case 'zip':
$mimetype = "zip"; $mimetype = 'zip';
$file_ext = "zip"; $file_ext = 'zip';
break; break;
default: default:
$mimetype = NULL; $mimetype = NULL;
@ -43,7 +42,7 @@ if ( $archivetype ) {
if ( $mimetype ) { if ( $mimetype ) {
$filename = "zmExport.$file_ext"; $filename = "zmExport.$file_ext";
$filename_path = ZM_DIR_TEMP."/".$filename; $filename_path = ZM_DIR_EXPORTS.'/'.$filename;
if ( is_readable($filename_path) ) { if ( is_readable($filename_path) ) {
header( "Content-type: application/$mimetype" ); header( "Content-type: application/$mimetype" );
header( "Content-Disposition: attachment; filename=$filename"); header( "Content-Disposition: attachment; filename=$filename");

View File

@ -66,7 +66,6 @@ if ( empty($_REQUEST['path']) ) {
$Frame = new Frame(); $Frame = new Frame();
$Frame->FrameId('snapshot'); $Frame->FrameId('snapshot');
$path = $Event->Path().'/snapshot.jpg'; $path = $Event->Path().'/snapshot.jpg';
Warning("Path to snapshot: $path");
} else { } else {
$show = empty($_REQUEST['show']) ? 'capture' : $_REQUEST['show']; $show = empty($_REQUEST['show']) ? 'capture' : $_REQUEST['show'];