Merge branch 'master' of github.com:ZoneMinder/zoneminder
This commit is contained in:
commit
a04f6df06a
|
@ -303,6 +303,7 @@ CREATE TABLE `Filters` (
|
|||
`UpdateDiskSpace` tinyint(3) unsigned NOT NULL default '0',
|
||||
`Background` tinyint(1) unsigned NOT NULL default '0',
|
||||
`Concurrent` tinyint(1) unsigned NOT NULL default '0',
|
||||
`LockRows` tinyint(1) unsigned NOT NULL default '0',
|
||||
PRIMARY KEY (`Id`),
|
||||
KEY `Name` (`Name`)
|
||||
) ENGINE=@ZM_MYSQL_ENGINE@;
|
||||
|
@ -315,6 +316,7 @@ DROP TABLE IF EXISTS `Frames`;
|
|||
CREATE TABLE `Frames` (
|
||||
`Id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`EventId` BIGINT UNSIGNED NOT NULL default '0',
|
||||
FOREIGN KEY (`EventId`) REFERENCES `Events` (`Id`) ON DELETE CASCADE,
|
||||
`FrameId` int(10) unsigned NOT NULL default '0',
|
||||
`Type` enum('Normal','Bulk','Alarm') NOT NULL default 'Normal',
|
||||
`TimeStamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
|
||||
|
@ -608,8 +610,11 @@ DROP TABLE IF EXISTS `Stats`;
|
|||
CREATE TABLE `Stats` (
|
||||
`Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`MonitorId` int(10) unsigned NOT NULL default '0',
|
||||
FOREIGN KEY (`MonitorId`) REFERENCES `Monitors` (`Id`) ON DELETE CASCADE,
|
||||
`ZoneId` int(10) unsigned NOT NULL default '0',
|
||||
FOREIGN KEY (`ZoneId`) REFERENCES `Zones` (`Id`) ON DELETE CASCADE,
|
||||
`EventId` BIGINT UNSIGNED NOT NULL,
|
||||
FOREIGN KEY (`EventId`) REFERENCES `Events` (`Id`) ON DELETE CASCADE,
|
||||
`FrameId` int(10) unsigned NOT NULL default '0',
|
||||
`PixelDiff` tinyint(3) unsigned NOT NULL default '0',
|
||||
`AlarmPixels` int(10) unsigned NOT NULL default '0',
|
||||
|
@ -704,6 +709,7 @@ DROP TABLE IF EXISTS `Zones`;
|
|||
CREATE TABLE `Zones` (
|
||||
`Id` int(10) unsigned NOT NULL auto_increment,
|
||||
`MonitorId` int(10) unsigned NOT NULL default '0',
|
||||
FOREIGN KEY (`MonitorId`) REFERENCES `Monitors` (`Id`) ON DELETE CASCADE,
|
||||
`Name` varchar(64) NOT NULL default '',
|
||||
`Type` enum('Active','Inclusive','Exclusive','Preclusive','Inactive','Privacy') NOT NULL default 'Active',
|
||||
`Units` enum('Pixels','Percent') NOT NULL default 'Pixels',
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/* Change Id type to BIGINT. */
|
||||
set @exist := (SELECT count(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'Events' AND COLUMN_NAME = 'Id' and DATA_TYPE='bigint');
|
||||
|
||||
set @sqlstmt := if( @exist = 0, "ALTER TABLE Events MODIFY Id bigint unsigned NOT NULL auto_increment", "SELECT 'Ok'");
|
||||
PREPARE stmt FROM @sqlstmt;
|
||||
EXECUTE stmt;
|
||||
|
||||
/* Add FOREIGN KEYS After deleting lost records */
|
||||
set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Frames' and column_name='EventId' and referenced_table_name='Events' and referenced_column_name='Id');
|
||||
|
||||
set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'");
|
||||
set @sqlstmt := if( @exist = 1, "SELECT 'FOREIGN KEY EventId in Frames already exists'", @sqlstmt);
|
||||
set @sqlstmt := if( @exist = 0, "SELECT 'Adding foreign key for EventId to Frames'", @sqlstmt);
|
||||
PREPARE stmt FROM @sqlstmt;
|
||||
EXECUTE stmt;
|
||||
|
||||
set @sqlstmt := if( @exist != 0, "SELECT '.'", "SELECT 'Deleting unlinked Frames'");
|
||||
PREPARE stmt FROM @sqlstmt;
|
||||
EXECUTE stmt;
|
||||
set @sqlstmt := if( @exist != 0, "SELECT '.'", "DELETE FROM Frames WHERE EventId NOT IN (SELECT Id FROM Events)");
|
||||
PREPARE stmt FROM @sqlstmt;
|
||||
EXECUTE stmt;
|
||||
set @sqlstmt := if( @exist != 0, "SELECT 'Ok'", "ALTER TABLE Frames ADD FOREIGN KEY (EventId) REFERENCES Events (Id) ON DELETE CASCADE");
|
||||
PREPARE stmt FROM @sqlstmt;
|
||||
EXECUTE stmt;
|
||||
|
||||
|
||||
SELECT 'Adding foreign key for EventId to Stats';
|
||||
set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Stats' and column_name='EventId' and referenced_table_name='Events' and referenced_column_name='Id');
|
||||
set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'");
|
||||
set @sqlstmt := if( @exist = 1, "SELECT 'FOREIGN KEY already EventId in Stats already exists'", @sqlstmt);
|
||||
set @sqlstmt := if( @exist = 0, "SELECT 'Adding FOREIGN KEY for EventId to Stats'", @sqlstmt);
|
||||
PREPARE stmt FROM @sqlstmt;
|
||||
EXECUTE stmt;
|
||||
|
||||
set @sqlstmt := if( @exist > 0, "SELECT 'FOREIGN KEY for EventId in Stats already exists'", "DELETE FROM Stats WHERE EventId NOT IN (SELECT Id FROM Events);");
|
||||
PREPARE stmt FROM @sqlstmt;
|
||||
EXECUTE stmt;
|
||||
|
||||
set @sqlstmt := if( @exist > 0, "SELECT 'Ok'", "ALTER TABLE Stats ADD FOREIGN KEY (EventId) REFERENCES Events (Id) ON DELETE CASCADE");
|
||||
PREPARE stmt FROM @sqlstmt;
|
||||
EXECUTE stmt;
|
||||
|
||||
|
||||
SELECT 'Adding foreign key for MonitorId to Stats';
|
||||
set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Stats' and column_name='MonitorId' and referenced_table_name='Monitors' and referenced_column_name='Id');
|
||||
set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'");
|
||||
PREPARE stmt FROM @sqlstmt;
|
||||
EXECUTE stmt;
|
||||
|
||||
set @sqlstmt := if( @exist > 0, "SELECT 'FOREIGN KEY for MonitorId in Stats already exists'", "DELETE FROM Stats WHERE MonitorId NOT IN (SELECT Id FROM Monitors);");
|
||||
PREPARE stmt FROM @sqlstmt;
|
||||
EXECUTE stmt;
|
||||
|
||||
set @sqlstmt := if( @exist > 0, "SELECT 'Ok'", "ALTER TABLE Stats ADD FOREIGN KEY (MonitorId) REFERENCES Monitors (Id) ON DELETE CASCADE");
|
||||
PREPARE stmt FROM @sqlstmt;
|
||||
EXECUTE stmt;
|
||||
|
||||
SELECT 'Adding foreign key for ZoneId to Stats';
|
||||
set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Stats' and column_name='ZoneId' and referenced_table_name='Zones' and referenced_column_name='Id');
|
||||
set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'");
|
||||
PREPARE stmt FROM @sqlstmt;
|
||||
EXECUTE stmt;
|
||||
|
||||
set @sqlstmt := if( @exist > 0, "SELECT 'FOREIGN KEY for ZoneId in Stats already exists'", "DELETE FROM Stats WHERE ZoneId NOT IN (SELECT Id FROM Zones);");
|
||||
PREPARE stmt FROM @sqlstmt;
|
||||
EXECUTE stmt;
|
||||
|
||||
set @sqlstmt := if( @exist > 0, "SELECT 'Ok'", "ALTER TABLE Stats ADD FOREIGN KEY (ZoneId) REFERENCES Zones (Id) ON DELETE CASCADE");
|
||||
PREPARE stmt FROM @sqlstmt;
|
||||
EXECUTE stmt;
|
||||
|
||||
SELECT 'Adding foreign key for MonitorId to Zones';
|
||||
set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Zones' and column_name='MonitorId' and referenced_table_name='Monitors' and referenced_column_name='Id');
|
||||
set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'");
|
||||
PREPARE stmt FROM @sqlstmt;
|
||||
EXECUTE stmt;
|
||||
|
||||
set @sqlstmt := if( @exist > 0, "SELECT 'FOREIGN KEY for MonitorId in Zones already exists'", "SELECT 'FOREIGN KEY for MonitorId in Zones does not already exist'");
|
||||
set @badzones := (select count(*) FROM Zones WHERE MonitorId NOT IN (SELECT Id FROM Monitors));
|
||||
set @sqlstmt := if ( @badzones > 0, "SELECT 'You have Zones with no Monitor record in the Monitors table. Please delete them manually'", "ALTER TABLE Zones ADD FOREIGN KEY (MonitorId) REFERENCES Monitors (Id)");
|
||||
PREPARE stmt FROM @sqlstmt;
|
||||
EXECUTE stmt;
|
|
@ -0,0 +1,18 @@
|
|||
--
|
||||
-- Update Filters table to have a LockRows Column
|
||||
--
|
||||
|
||||
SELECT 'Checking for LockRows in Filters';
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE table_name = 'Filters'
|
||||
AND table_schema = DATABASE()
|
||||
AND column_name = 'LockRows'
|
||||
) > 0,
|
||||
"SELECT 'Column LockRows already exists in Filters'",
|
||||
"ALTER TABLE Filters ADD COLUMN `LockRows` tinyint(1) unsigned NOT NULL default '0' AFTER `Concurrent`"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
|
@ -39,9 +39,9 @@ if [ "$1" = "configure" ]; then
|
|||
exit 1;
|
||||
fi
|
||||
# This creates the user.
|
||||
echo "grant lock tables, alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost identified by \"${ZM_DB_PASS}\";" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||
echo "grant lock tables, alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute, REFERENCES on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost identified by \"${ZM_DB_PASS}\";" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||
else
|
||||
echo "grant lock tables, alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||
echo "grant lock tables, alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute, REFERENCES on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||
fi
|
||||
|
||||
zmupdate.pl --nointeractive
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
%global _hardened_build 1
|
||||
|
||||
Name: zoneminder
|
||||
Version: 1.35.10
|
||||
Version: 1.35.12
|
||||
Release: 1%{?dist}
|
||||
Summary: A camera monitoring and analysis tool
|
||||
Group: System Environment/Daemons
|
||||
|
|
|
@ -67,8 +67,8 @@ if [ "$1" = "configure" ]; then
|
|||
# This creates the user.
|
||||
echo "CREATE USER '${ZM_DB_USER}'@localhost IDENTIFIED BY '${ZM_DB_PASS}';" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||
fi
|
||||
echo "Updating permissions"
|
||||
echo "grant lock tables,alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||
echo "Updating permissions for user ${ZM_DB_USER}@localhost"
|
||||
echo "GRANT LOCK TABLES,ALTER,DROP,SELECT,INSERT,UPDATE,DELETE,CREATE,INDEX,ALTER ROUTINE,CREATE ROUTINE, TRIGGER,EXECUTE,REFERENCES ON ${ZM_DB_NAME}.* TO '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||
|
||||
zmupdate.pl --nointeractive
|
||||
zmupdate.pl --nointeractive -f
|
||||
|
|
|
@ -25,8 +25,8 @@ create_update_user () {
|
|||
# This creates the user.
|
||||
echo "CREATE USER '${ZM_DB_USER}'@${ZM_DB_HOST} IDENTIFIED BY '${ZM_DB_PASS}';" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||
fi
|
||||
echo "Updating permissions"
|
||||
echo "GRANT LOCK tables,alter,drop,select,insert,update,delete,create,index,alter routine,create routine,trigger,execute ON ${ZM_DB_NAME}.* TO '${ZM_DB_USER}'@${ZM_DB_HOST};" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||
echo "Updating permissions for user ${ZM_DB_USER}@${ZM_DB_HOST}"
|
||||
echo "GRANT LOCK tables,alter,drop,select,insert,update,delete,create,index,alter routine,create routine,trigger,execute,REFERENCES ON ${ZM_DB_NAME}.* TO '${ZM_DB_USER}'@${ZM_DB_HOST};" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||
}
|
||||
|
||||
update_db () {
|
||||
|
|
|
@ -349,6 +349,10 @@ sub GenerateVideo {
|
|||
return;
|
||||
} # end sub GenerateVideo
|
||||
|
||||
# Note about transactions, this function may be called with rows locked and hence in a transaction.
|
||||
# So we will detect if we are in a transaction, and if not, start one. We will NOT do rollback or
|
||||
# commits unless we started the transaction.
|
||||
|
||||
sub delete {
|
||||
my $event = $_[0];
|
||||
|
||||
|
@ -378,23 +382,25 @@ sub delete {
|
|||
Info("Deleting event $event->{Id} from Monitor $event->{MonitorId} StartTime:$event->{StartTime} from ".$event->Path());
|
||||
$ZoneMinder::Database::dbh->ping();
|
||||
|
||||
$ZoneMinder::Database::dbh->begin_work();
|
||||
#$event->lock_and_load();
|
||||
my $in_transaction = $ZoneMinder::Database::dbh->{AutoCommit} ? 0 : 1;
|
||||
|
||||
ZoneMinder::Database::zmDbDo('DELETE FROM Frames WHERE EventId=?', $$event{Id});
|
||||
if ( $ZoneMinder::Database::dbh->errstr() ) {
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
return;
|
||||
}
|
||||
$ZoneMinder::Database::dbh->begin_work() if ! $in_transaction;
|
||||
|
||||
# Going to delete in order of least value to greatest value. Stats is least and references Frames
|
||||
ZoneMinder::Database::zmDbDo('DELETE FROM Stats WHERE EventId=?', $$event{Id});
|
||||
if ( $ZoneMinder::Database::dbh->errstr() ) {
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
$ZoneMinder::Database::dbh->commit() if ! $in_transaction;
|
||||
return;
|
||||
}
|
||||
ZoneMinder::Database::zmDbDo('DELETE FROM Frames WHERE EventId=?', $$event{Id});
|
||||
if ( $ZoneMinder::Database::dbh->errstr() ) {
|
||||
$ZoneMinder::Database::dbh->commit() if ! $in_transaction;
|
||||
return;
|
||||
}
|
||||
|
||||
# Do it individually to avoid locking up the table for new events
|
||||
ZoneMinder::Database::zmDbDo('DELETE FROM Events WHERE Id=?', $$event{Id});
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
$ZoneMinder::Database::dbh->commit() if ! $in_transaction;
|
||||
}
|
||||
|
||||
if ( ( $in_zmaudit or (!$Config{ZM_OPT_FAST_DELETE})) and $event->Storage()->DoDelete() ) {
|
||||
|
|
|
@ -77,6 +77,7 @@ UpdateDiskSpace
|
|||
UserId
|
||||
Background
|
||||
Concurrent
|
||||
LockRows
|
||||
);
|
||||
|
||||
sub Execute {
|
||||
|
@ -103,6 +104,8 @@ sub Execute {
|
|||
$sql =~ s/zmSystemLoad/$load/g;
|
||||
}
|
||||
|
||||
$sql .= ' FOR UPDATE' if $$self{LockRows};
|
||||
|
||||
Debug("Filter::Execute SQL ($sql)");
|
||||
my $sth = $ZoneMinder::Database::dbh->prepare_cached($sql)
|
||||
or Fatal("Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr());
|
||||
|
|
|
@ -504,9 +504,9 @@ sub openFile {
|
|||
$LOGFILE->autoflush() if $this->{autoFlush};
|
||||
|
||||
my $webUid = (getpwnam($ZoneMinder::Config::Config{ZM_WEB_USER}))[2];
|
||||
Error("Can't get uid for $ZoneMinder::Config::Config{ZM_WEB_USER}") if ! defined $webUid;
|
||||
Error('Can\'t get uid for '.$ZoneMinder::Config::Config{ZM_WEB_USER}) if ! defined $webUid;
|
||||
my $webGid = (getgrnam($ZoneMinder::Config::Config{ZM_WEB_GROUP}))[2];
|
||||
Error("Can't get gid for $ZoneMinder::Config::Config{ZM_WEB_USER}") if ! defined $webGid;
|
||||
Error('Can\'t get gid for '.$ZoneMinder::Config::Config{ZM_WEB_USER}) if ! defined $webGid;
|
||||
if ( $> == 0 ) {
|
||||
# If we are root, we want to make sure that www-data or whatever owns the file
|
||||
chown($webUid, $webGid, $this->{logFile} ) or
|
||||
|
@ -610,6 +610,7 @@ sub logInit( ;@ ) {
|
|||
my %options = @_ ? @_ : ();
|
||||
$logger = ZoneMinder::Logger->new() if !$logger;
|
||||
$logger->initialise(%options);
|
||||
logSetSignal();
|
||||
}
|
||||
|
||||
sub logReinit {
|
||||
|
@ -626,12 +627,26 @@ sub logHupHandler {
|
|||
$do_log_rotate = 1;
|
||||
}
|
||||
|
||||
sub logUSR1Handler {
|
||||
$logger->level($logger->level()+1);
|
||||
Info('Logger - Level changed to '. $logger->level() . '=>'.$codes{$logger->level()});
|
||||
}
|
||||
|
||||
sub logUSR2Handler {
|
||||
$logger->level($logger->level()-1);
|
||||
Info('Logger - Level changed to '. $logger->level() . '=>'.$codes{$logger->level()});
|
||||
}
|
||||
|
||||
sub logSetSignal {
|
||||
$SIG{HUP} = \&logHupHandler;
|
||||
$SIG{USR1} = \&logUSR1Handler;
|
||||
$SIG{USR2} = \&logUSR2Handler;
|
||||
}
|
||||
|
||||
sub logClearSignal {
|
||||
$SIG{HUP} = 'DEFAULT';
|
||||
$SIG{USR1} = 'DEFAULT';
|
||||
$SIG{USR2} = 'DEFAULT';
|
||||
}
|
||||
|
||||
sub logLevel {
|
||||
|
|
|
@ -277,6 +277,7 @@ FILTER: while( my $db_filter = $sth->fetchrow_hashref() ) {
|
|||
sub checkFilter {
|
||||
my $filter = shift;
|
||||
|
||||
my $in_transaction = ZoneMinder::Database::start_transaction($dbh) if $$filter{LockRows};
|
||||
my @Events = $filter->Execute();
|
||||
Debug(
|
||||
join(' ',
|
||||
|
@ -396,6 +397,7 @@ sub checkFilter {
|
|||
$ZoneMinder::Database::dbh->commit();
|
||||
} # end if UpdateDiskSpace
|
||||
} # end foreach event
|
||||
ZoneMinder::Database::end_transaction($dbh, $in_transaction) if $$filter{LockRows};
|
||||
} # end sub checkFilter
|
||||
|
||||
sub generateVideo {
|
||||
|
|
|
@ -664,7 +664,6 @@ int FfmpegCamera::OpenFfmpeg() {
|
|||
} // int FfmpegCamera::OpenFfmpeg()
|
||||
|
||||
int FfmpegCamera::Close() {
|
||||
Debug(2, "CloseFfmpeg called.");
|
||||
|
||||
mCanCapture = false;
|
||||
|
||||
|
|
|
@ -29,15 +29,13 @@
|
|||
bool zm_reload = false;
|
||||
bool zm_terminate = false;
|
||||
|
||||
RETSIGTYPE zm_hup_handler(int signal)
|
||||
{
|
||||
RETSIGTYPE zm_hup_handler(int signal) {
|
||||
// Shouldn't do complex things in signal handlers, logging is complex and can block due to mutexes.
|
||||
//Info("Got signal %d (%s), reloading", signal, strsignal(signal));
|
||||
zm_reload = true;
|
||||
}
|
||||
|
||||
RETSIGTYPE zm_term_handler(int signal)
|
||||
{
|
||||
RETSIGTYPE zm_term_handler(int signal) {
|
||||
// Shouldn't do complex things in signal handlers, logging is complex and can block due to mutexes.
|
||||
//Info("Got signal %d (%s), exiting", signal, strsignal(signal));
|
||||
zm_terminate = true;
|
||||
|
@ -55,8 +53,7 @@ RETSIGTYPE zm_die_handler(int signal)
|
|||
#if ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T )
|
||||
void *ip = nullptr;
|
||||
void *cr2 = nullptr;
|
||||
if (info && context) {
|
||||
|
||||
if ( info && context ) {
|
||||
Debug(1,
|
||||
"Signal information: number %d code %d errno %d pid %d uid %d status %d",
|
||||
signal, info->si_code, info->si_errno, info->si_pid,
|
||||
|
@ -79,7 +76,7 @@ RETSIGTYPE zm_die_handler(int signal)
|
|||
#endif // defined(__x86_64__)
|
||||
|
||||
// Print the signal address and instruction pointer if available
|
||||
if (ip) {
|
||||
if ( ip ) {
|
||||
Error("Signal address is %p, from %p", cr2, ip);
|
||||
} else {
|
||||
Error("Signal address is %p, no instruction pointer", cr2);
|
||||
|
@ -115,8 +112,7 @@ RETSIGTYPE zm_die_handler(int signal)
|
|||
exit(signal);
|
||||
}
|
||||
|
||||
void zmSetHupHandler(SigHandler * handler)
|
||||
{
|
||||
void zmSetHupHandler(SigHandler * handler) {
|
||||
sigset_t block_set;
|
||||
sigemptyset(&block_set);
|
||||
struct sigaction action, old_action;
|
||||
|
@ -127,8 +123,7 @@ void zmSetHupHandler(SigHandler * handler)
|
|||
sigaction(SIGHUP, &action, &old_action);
|
||||
}
|
||||
|
||||
void zmSetTermHandler(SigHandler * handler)
|
||||
{
|
||||
void zmSetTermHandler(SigHandler * handler) {
|
||||
sigset_t block_set;
|
||||
sigemptyset(&block_set);
|
||||
struct sigaction action, old_action;
|
||||
|
@ -141,8 +136,7 @@ void zmSetTermHandler(SigHandler * handler)
|
|||
sigaction(SIGQUIT, &action, &old_action);
|
||||
}
|
||||
|
||||
void zmSetDieHandler(SigHandler * handler)
|
||||
{
|
||||
void zmSetDieHandler(SigHandler * handler) {
|
||||
sigset_t block_set;
|
||||
sigemptyset(&block_set);
|
||||
struct sigaction action, old_action;
|
||||
|
@ -163,19 +157,16 @@ void zmSetDieHandler(SigHandler * handler)
|
|||
sigaction(SIGFPE, &action, &old_action);
|
||||
}
|
||||
|
||||
void zmSetDefaultHupHandler()
|
||||
{
|
||||
void zmSetDefaultHupHandler() {
|
||||
zmSetHupHandler((SigHandler *) zm_hup_handler);
|
||||
}
|
||||
|
||||
void zmSetDefaultTermHandler()
|
||||
{
|
||||
void zmSetDefaultTermHandler() {
|
||||
zmSetTermHandler((SigHandler *) zm_term_handler);
|
||||
}
|
||||
|
||||
void zmSetDefaultDieHandler()
|
||||
{
|
||||
if (config.dump_cores) {
|
||||
void zmSetDefaultDieHandler() {
|
||||
if ( config.dump_cores ) {
|
||||
// Do nothing
|
||||
} else {
|
||||
zmSetDieHandler((SigHandler *) zm_die_handler);
|
||||
|
|
|
@ -115,6 +115,19 @@ function deleteRequest($eid) {
|
|||
}
|
||||
|
||||
function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $limit) {
|
||||
$data = array(
|
||||
'total' => 0,
|
||||
'totalNotFiltered' => 0,
|
||||
'rows' => array(),
|
||||
'updated' => preg_match('/%/', DATE_FMT_CONSOLE_LONG) ? strftime(DATE_FMT_CONSOLE_LONG) : date(DATE_FMT_CONSOLE_LONG)
|
||||
);
|
||||
|
||||
$failed = !$filter->test_pre_sql_conditions();
|
||||
if ( $failed ) {
|
||||
ZM\Debug('Pre conditions failed, not doing sql');
|
||||
return $data;
|
||||
}
|
||||
|
||||
// Put server pagination code here
|
||||
// The table we want our data from
|
||||
$table = 'Events';
|
||||
|
@ -126,7 +139,8 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim
|
|||
$col_alt = array('Monitor', 'Storage');
|
||||
|
||||
if ( !in_array($sort, array_merge($columns, $col_alt)) ) {
|
||||
ZM\Fatal('Invalid sort field: ' . $sort);
|
||||
ZM\Error('Invalid sort field: ' . $sort);
|
||||
$sort = 'Id';
|
||||
}
|
||||
|
||||
$data = array();
|
||||
|
@ -140,44 +154,39 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim
|
|||
if ( count($advsearch) ) {
|
||||
|
||||
foreach ( $advsearch as $col=>$text ) {
|
||||
if ( !in_array($col, array_merge($columns, $col_alt)) ) {
|
||||
if ( in_array($col, $columns) ) {
|
||||
array_push($likes, 'E.'.$col.' LIKE ?');
|
||||
array_push($query['values'], $text);
|
||||
} else if ( in_array($col, $col_alt) ) {
|
||||
array_push($likes, 'M.'.$col.' LIKE ?');
|
||||
array_push($query['values'], $text);
|
||||
} else {
|
||||
ZM\Error("'$col' is not a sortable column name");
|
||||
continue;
|
||||
}
|
||||
$text = '%' .$text. '%';
|
||||
array_push($likes, $col.' LIKE ?');
|
||||
array_push($query['values'], $text);
|
||||
}
|
||||
} # end foreach col in advsearch
|
||||
$wherevalues = $query['values'];
|
||||
$where = ' AND (' .implode(' OR ', $likes). ')';
|
||||
$where .= ($where != '') ? ' AND (' .implode(' OR ', $likes). ')' : implode(' OR ', $likes);
|
||||
|
||||
} else if ( $search != '' ) {
|
||||
|
||||
$search = '%' .$search. '%';
|
||||
foreach ( $columns as $col ) {
|
||||
array_push($likes, $col.' LIKE ?');
|
||||
array_push($likes, 'E.'.$col.' LIKE ?');
|
||||
array_push($query['values'], $search);
|
||||
}
|
||||
$wherevalues = $query['values'];
|
||||
$where = ' AND (' .implode(' OR ', $likes). ')';
|
||||
$where .= ( $where != '') ? ' AND (' .implode(' OR ', $likes). ')' : implode(' OR ', $likes);
|
||||
}
|
||||
if ( $where )
|
||||
$where = ' WHERE '.$where;
|
||||
|
||||
$sort = $sort == "Monitor" ? 'M.Name' : 'E.'.$sort;
|
||||
$sort = $sort == 'Monitor' ? 'M.Name' : 'E.'.$sort;
|
||||
$col_str = 'E.*, M.Name AS Monitor';
|
||||
//$query['sql'] = 'SELECT ' .$col_str. ' FROM `' .$table. '` AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id'.$where.' ORDER BY LENGTH(' .$sort. '), ' .$sort. ' ' .$order. ' LIMIT ?, ?';
|
||||
$query['sql'] = 'SELECT ' .$col_str. ' FROM `' .$table. '` AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id'.$where.' ORDER BY ' .$sort. ' ' .$order. ' LIMIT ?, ?';
|
||||
array_push($query['values'], $offset, $limit);
|
||||
|
||||
ZM\Warning('Calling the following sql query: ' .$query['sql']);
|
||||
|
||||
$data['totalNotFiltered'] = dbFetchOne('SELECT count(*) AS Total FROM ' .$table . ' AS E'. ($filter->sql() ? ' WHERE '.$filter->sql():''), 'Total');
|
||||
if ( $search != '' || count($advsearch) ) {
|
||||
$data['total'] = dbFetchOne('SELECT count(*) AS Total FROM ' .$table . ' AS E'.$where , 'Total', $wherevalues);
|
||||
} else {
|
||||
$data['total'] = $data['totalNotFiltered'];
|
||||
}
|
||||
//ZM\Debug('Calling the following sql query: ' .$query['sql']);
|
||||
|
||||
$storage_areas = ZM\Storage::find();
|
||||
$StorageById = array();
|
||||
|
@ -187,8 +196,11 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim
|
|||
|
||||
$rows = array();
|
||||
foreach ( dbFetchAll($query['sql'], NULL, $query['values']) as $row ) {
|
||||
ZM\Debug("row".print_r($row,true));
|
||||
$event = new ZM\Event($row);
|
||||
if ( !$filter->test_post_sql_conditions($event) ) {
|
||||
$event->remove_from_cache();
|
||||
continue;
|
||||
}
|
||||
$scale = intval(5*100*ZM_WEB_LIST_THUMB_WIDTH / $event->Width());
|
||||
$imgSrc = $event->getThumbnailSrc(array(),'&');
|
||||
$streamSrc = $event->getStreamSrc(array(
|
||||
|
@ -201,16 +213,18 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim
|
|||
$row['Emailed'] = $row['Emailed'] ? translate('Yes') : translate('No');
|
||||
$row['Cause'] = validHtmlStr($row['Cause']);
|
||||
$row['StartTime'] = strftime(STRF_FMT_DATETIME_SHORTER, strtotime($row['StartTime']));
|
||||
$row['EndTime'] = strftime(STRF_FMT_DATETIME_SHORTER, strtotime($row['StartTime']));
|
||||
$row['EndTime'] = strftime(STRF_FMT_DATETIME_SHORTER, strtotime($row['EndTime']));
|
||||
$row['Length'] = gmdate('H:i:s', $row['Length'] );
|
||||
$row['Storage'] = ( $row['StorageId'] and isset($StorageById[$row['StorageId']]) ) ? $StorageById[$row['StorageId']]->Name() : 'Default';
|
||||
$row['Notes'] = htmlspecialchars($row['Notes']);
|
||||
$row['Notes'] = nl2br(htmlspecialchars($row['Notes']));
|
||||
$row['DiskSpace'] = human_filesize($event->DiskSpace());
|
||||
$rows[] = $row;
|
||||
}
|
||||
$data['rows'] = $rows;
|
||||
$data['updated'] = preg_match('/%/', DATE_FMT_CONSOLE_LONG) ? strftime(DATE_FMT_CONSOLE_LONG) : date(DATE_FMT_CONSOLE_LONG);
|
||||
|
||||
# total has to be the # of available rows. Not sure what totalNotFiltered is actually used for yet.
|
||||
$data['totalNotFiltered'] = $data['total'] = dbFetchOne('SELECT count(*) AS Total FROM ' .$table. ' AS E'. ($filter->sql() ? ' WHERE '.$filter->sql():''), 'Total');
|
||||
#$data['total'] = count($rows);
|
||||
return $data;
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -66,7 +66,7 @@ if ( isset($_REQUEST['limit']) ) {
|
|||
|
||||
switch ( $task ) {
|
||||
case 'create' :
|
||||
createRequest($task, $eid);
|
||||
createRequest();
|
||||
break;
|
||||
case 'query' :
|
||||
$data = queryRequest($search, $advsearch, $sort, $offset, $order, $limit);
|
||||
|
|
|
@ -6,6 +6,7 @@ if ( $_REQUEST['entity'] == 'navBar' ) {
|
|||
$auth_hash = generateAuthHash(ZM_AUTH_HASH_IPS);
|
||||
if ( isset($_REQUEST['auth']) and ($_REQUEST['auth'] != $auth_hash) ) {
|
||||
$data['auth'] = $auth_hash;
|
||||
$data['auth_relay'] = get_auth_relay();
|
||||
}
|
||||
}
|
||||
// Each widget on the navbar has its own function
|
||||
|
|
|
@ -29,6 +29,7 @@ class Filter extends ZM_Object {
|
|||
'Background' => 0,
|
||||
'Concurrent' => 0,
|
||||
'Query_json' => '',
|
||||
'LockRows' => 0,
|
||||
);
|
||||
|
||||
protected $_querystring;
|
||||
|
|
|
@ -408,10 +408,10 @@ class Logger {
|
|||
}
|
||||
}
|
||||
|
||||
$message = $code.' ['.$string.']';
|
||||
if ( $level <= $this->syslogLevel )
|
||||
syslog( self::$syslogPriorities[$level], $message );
|
||||
syslog(self::$syslogPriorities[$level], $message);
|
||||
|
||||
$message = $code.' ['.$string.']';
|
||||
if ( $level <= $this->databaseLevel ) {
|
||||
try {
|
||||
global $dbConn;
|
||||
|
|
|
@ -371,6 +371,7 @@ $SLANG = array(
|
|||
'FilterUpdateDiskSpace' => 'Update used disk space',
|
||||
'FilterDeleteEvents' => 'Delete all matches',
|
||||
'FilterCopyEvents' => 'Copy all matches',
|
||||
'FilterLockRows' => 'Lock Rows',
|
||||
'FilterMoveEvents' => 'Move all matches',
|
||||
'FilterEmailEvents' => 'Email details of all matches',
|
||||
'FilterEmailTo' => 'Email To',
|
||||
|
|
|
@ -351,6 +351,11 @@ if ( currentView != 'none' && currentView != 'login' ) {
|
|||
.done(setNavBar)
|
||||
.fail(function(jqxhr, textStatus, error) {
|
||||
console.log("Request Failed: " + textStatus + ", " + error);
|
||||
if ( ! jqxhr.responseText ) {
|
||||
console.log("No responseText in jqxhr");
|
||||
console.log(jqxhr);
|
||||
return;
|
||||
}
|
||||
console.log("Response Text: " + jqxhr.responseText.replace(/(<([^>]+)>)/gi, ''));
|
||||
if ( textStatus != "timeout" ) {
|
||||
// The idea is that this should only fail due to auth, so reload the page
|
||||
|
@ -367,10 +372,14 @@ if ( currentView != 'none' && currentView != 'login' ) {
|
|||
}
|
||||
if ( data.auth ) {
|
||||
if ( data.auth != auth_hash ) {
|
||||
console.log("Update auth_hash to "+data.auth);
|
||||
// Update authentication token.
|
||||
auth_hash = data.auth;
|
||||
}
|
||||
}
|
||||
if ( data.auth_relay ) {
|
||||
auth_relay = data.auth_relay;
|
||||
}
|
||||
// iterate through all the keys then update each element id with the same name
|
||||
for (var key of Object.keys(data)) {
|
||||
if ( key == "auth" ) continue;
|
||||
|
|
|
@ -42,73 +42,6 @@ if ( isset($_REQUEST['filter'])) {
|
|||
parseSort();
|
||||
|
||||
$filterQuery = $filter->querystring();
|
||||
ZM\Debug('Filter '.print_r($filter, true));
|
||||
|
||||
if ( $filter->sql() ) {
|
||||
$eventsSql .= ' AND ('.$filter->sql().')';
|
||||
} else {
|
||||
ZM\Warning('No filters');
|
||||
exit;
|
||||
}
|
||||
$eventsSql .= ' ORDER BY '.$sortColumn.' '.$sortOrder;
|
||||
if ( $sortColumn != 'E.Id' ) $eventsSql .= ',E.Id '.$sortOrder;
|
||||
|
||||
$page = isset($_REQUEST['page']) ? validInt($_REQUEST['page']) : 0;
|
||||
$limit = isset($_REQUEST['limit']) ? validInt($_REQUEST['limit']) : $filter['limit'];
|
||||
|
||||
if ( $_POST ) {
|
||||
// I think this is basically so that a refresh doesn't repost
|
||||
ZM\Debug('Redirecting to ' . $_SERVER['REQUEST_URI']);
|
||||
header('Location: ?view=' . $view.htmlspecialchars_decode($filterQuery).htmlspecialchars_decode($sortQuery).$limitQuery.'&page='.$page);
|
||||
exit();
|
||||
}
|
||||
|
||||
$failed = !$filter->test_pre_sql_conditions();
|
||||
if ( $failed ) {
|
||||
ZM\Debug('Pre conditions failed, not doing sql');
|
||||
}
|
||||
|
||||
$results = $failed ? null : dbQuery($eventsSql);
|
||||
|
||||
$nEvents = $results ? $results->rowCount() : 0;
|
||||
if ( ! $results ) {
|
||||
global $error_message;
|
||||
$error_message = dbError($eventsSql);
|
||||
}
|
||||
ZM\Debug("Pre conditions succeeded sql return $nEvents events");
|
||||
|
||||
if ( !empty($limit) && ($nEvents > $limit) ) {
|
||||
$nEvents = $limit;
|
||||
}
|
||||
$pages = (int)ceil($nEvents/ZM_WEB_EVENTS_PER_PAGE);
|
||||
#Debug("Page $page Limit $limit #vents: $nEvents pages: $pages ");
|
||||
if ( !empty($page) ) {
|
||||
if ( $page < 0 )
|
||||
$page = 1;
|
||||
else if ( $pages and ( $page > $pages ) )
|
||||
$page = $pages;
|
||||
|
||||
$limitStart = (($page-1)*ZM_WEB_EVENTS_PER_PAGE);
|
||||
if ( empty($limit) ) {
|
||||
$limitAmount = ZM_WEB_EVENTS_PER_PAGE;
|
||||
} else {
|
||||
$limitLeft = $limit - $limitStart;
|
||||
$limitAmount = ($limitLeft>ZM_WEB_EVENTS_PER_PAGE)?ZM_WEB_EVENTS_PER_PAGE:$limitLeft;
|
||||
}
|
||||
$eventsSql .= ' LIMIT '.$limitStart.', '.$limitAmount;
|
||||
} else if ( !empty($limit) ) {
|
||||
$eventsSql .= ' LIMIT 0, '.$limit;
|
||||
}
|
||||
|
||||
$maxShortcuts = 5;
|
||||
|
||||
$focusWindow = true;
|
||||
|
||||
$storage_areas = ZM\Storage::find();
|
||||
$StorageById = array();
|
||||
foreach ( $storage_areas as $S ) {
|
||||
$StorageById[$S->Id()] = $S;
|
||||
}
|
||||
|
||||
xhtmlHeaders(__FILE__, translate('Events'));
|
||||
getBodyTopHTML();
|
||||
|
@ -136,6 +69,8 @@ getBodyTopHTML();
|
|||
<table
|
||||
id="eventTable"
|
||||
data-locale="<?php echo i18n() ?>"
|
||||
data-side-pagination="server"
|
||||
data-ajax="ajaxRequest"
|
||||
data-pagination="true"
|
||||
data-show-pagination-switch="true"
|
||||
data-page-list="[10, 25, 50, 100, 200, All]"
|
||||
|
@ -155,6 +90,7 @@ getBodyTopHTML();
|
|||
data-mobile-responsive="true"
|
||||
data-buttons-class="btn btn-normal"
|
||||
data-show-jump-to="true"
|
||||
data-show-refresh="true"
|
||||
class="table-sm table-borderless"
|
||||
style="display:none;"
|
||||
>
|
||||
|
@ -168,163 +104,24 @@ getBodyTopHTML();
|
|||
<th data-sortable="true" data-field="Emailed"><?php echo translate('Emailed') ?></th>
|
||||
<th data-sortable="true" data-field="Monitor"><?php echo translate('Monitor') ?></th>
|
||||
<th data-sortable="true" data-field="Cause"><?php echo translate('Cause') ?></th>
|
||||
<th data-sortable="true" data-field="AttrStartTime"><?php echo translate('AttrStartTime') ?></th>
|
||||
<th data-sortable="true" data-field="AttrEndTime"><?php echo translate('AttrEndTime') ?></th>
|
||||
<th data-sortable="true" data-field="Duration"><?php echo translate('Duration') ?></th>
|
||||
<th data-sortable="true" data-field="StartTime"><?php echo translate('AttrStartTime') ?></th>
|
||||
<th data-sortable="true" data-field="EndTime"><?php echo translate('AttrEndTime') ?></th>
|
||||
<th data-sortable="true" data-field="Length"><?php echo translate('Duration') ?></th>
|
||||
<th data-sortable="true" data-field="Frames"><?php echo translate('Frames') ?></th>
|
||||
<th data-sortable="true" data-field="AlarmBrFrames"><?php echo translate('AlarmBrFrames') ?></th>
|
||||
<th data-sortable="true" data-field="TotalBrScore"><?php echo translate('TotalBrScore') ?></th>
|
||||
<th data-sortable="true" data-field="AvgBrScore"><?php echo translate('AvgBrScore') ?></th>
|
||||
<th data-sortable="true" data-field="MaxBrScore"><?php echo translate('MaxBrScore') ?></th>
|
||||
<?php
|
||||
if ( count($storage_areas) > 1 ) {
|
||||
?>
|
||||
<th data-sortable="true" data-field="Storage"><?php echo translate('Storage') ?></th>
|
||||
<?php
|
||||
}
|
||||
if ( ZM_WEB_EVENT_DISK_SPACE ) {
|
||||
?>
|
||||
<th data-sortable="true" data-field="AlarmFrames"><?php echo translate('AlarmBrFrames') ?></th>
|
||||
<th data-sortable="true" data-field="TotScore"><?php echo translate('TotalBrScore') ?></th>
|
||||
<th data-sortable="true" data-field="AvgScore"><?php echo translate('AvgBrScore') ?></th>
|
||||
<th data-sortable="true" data-field="MaxScore"><?php echo translate('MaxBrScore') ?></th>
|
||||
<th data-sortable="false" data-field="Storage"><?php echo translate('Storage') ?></th>
|
||||
<th data-sortable="true" data-field="DiskSpace"><?php echo translate('DiskSpace') ?></th>
|
||||
<?php
|
||||
}
|
||||
if ( ZM_WEB_LIST_THUMBS ) {
|
||||
?>
|
||||
<th data-sortable="false" data-field="Thumbnail"><?php echo translate('Thumbnail') ?></th>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<?php
|
||||
$count = 0;
|
||||
$disk_space_total = 0;
|
||||
if ( $results ) {
|
||||
$events = array();
|
||||
|
||||
while ( $event_row = dbFetchNext($results) ) {
|
||||
$event = new ZM\Event($event_row);
|
||||
|
||||
if ( !$filter->test_post_sql_conditions($event) ) {
|
||||
$event->remove_from_cache();
|
||||
continue;
|
||||
}
|
||||
$events[] = $event;
|
||||
if ( $limit and (count($events) >= $limit) ) {
|
||||
break;
|
||||
}
|
||||
ZM\Debug("Have " . count($events) . " events, limit $limit");
|
||||
}
|
||||
foreach ( $events as $event ) {
|
||||
|
||||
$scale = max(reScale(SCALE_BASE, $event->DefaultScale(), ZM_WEB_DEFAULT_SCALE), SCALE_BASE);
|
||||
?>
|
||||
<tr<?php echo $event->Archived() ? ' class="archived"' : '' ?>>
|
||||
<td data-checkbox="true"></td>
|
||||
<td><a href="?view=event&eid=<?php echo $event->Id().$filterQuery.$sortQuery.'&page=1">'.$event->Id() ?></a></td>
|
||||
|
||||
<td><a href="?view=event&eid=<?php echo $event->Id().$filterQuery.$sortQuery.'&page=1">'.validHtmlStr($event->Name())?></a>
|
||||
<?php
|
||||
$archived = $event->Archived() ? translate('Archived') : '';
|
||||
$emailed = $event->Emailed() ? ' '.translate('Emailed') : '';
|
||||
echo '<br/><div class="small text-nowrap text-muted">'.$archived.$emailed.'</div>';
|
||||
?>
|
||||
</td>
|
||||
|
||||
<td class="text-center"><?php echo ( $event->Archived() ) ? 'Yes' : 'No' ?></td>
|
||||
<td class="text-center"><?php echo ( $event->Emailed() ) ? 'Yes' : 'No' ?></td>
|
||||
<td><?php echo makeLink( '?view=monitor&mid='.$event->MonitorId(), $event->MonitorName(), canEdit( 'Monitors' ) ) ?></td>
|
||||
<td><?php echo makeLink( '#', validHtmlStr($event->Cause()), canEdit( 'Events' ), 'title="' .htmlspecialchars($event->Notes()). '" class="eDetailLink" data-eid=' .$event->Id(). '"') ?>
|
||||
<?php
|
||||
# display notes as small text
|
||||
if ( $event->Notes() ) {
|
||||
# if notes include detection objects, then link it to objdetect.jpg
|
||||
if ( strpos($event->Notes(), 'detected:') !== false ) {
|
||||
# make a link
|
||||
echo makeLink( '?view=image&eid='.$event->Id().'&fid=objdetect', '<div class="small text-nowrap text-muted"><u>'.$event->Notes().'</u></div>');
|
||||
} else if ( $event->Notes() != 'Forced Web: ' ) {
|
||||
echo '<br/><div class="small text-nowrap text-muted">'.$event->Notes().'</div>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
|
||||
<td><?php echo strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->StartTime())) ?></td>
|
||||
<td><?php echo strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->EndTime())) ?></td>
|
||||
<td><?php echo gmdate('H:i:s', $event->Length() ) ?></td>
|
||||
<td><a href="?view=frames&eid=<?php echo $event->Id() ?>"><?php echo $event->Frames() ?></a></td>
|
||||
<td><a href="?view=frames&eid=<?php echo $event->Id() ?>"><?php echo $event->AlarmFrames() ?></a></td>
|
||||
<td><?php echo $event->TotScore() ?></td>
|
||||
<td><?php echo $event->AvgScore() ?></td>
|
||||
<td><?php echo makeLink('?view=frame&eid='.$event->Id().'&fid=0', $event->MaxScore()); ?></td>
|
||||
<?php
|
||||
if ( count($storage_areas) > 1 ) {
|
||||
?>
|
||||
<td>
|
||||
<?php
|
||||
if ( $event->StorageId() ) {
|
||||
echo isset($StorageById[$event->StorageId()]) ? $StorageById[$event->StorageId()]->Name() : 'Unknown Storage Id: '.$event->StorageId();
|
||||
} else {
|
||||
echo 'Default';
|
||||
}
|
||||
if ( $event->SecondaryStorageId() ) {
|
||||
echo '<br/>'.(isset($StorageById[$event->SecondaryStorageId()]) ? $StorageById[$event->SecondaryStorageId()]->Name() : 'Unknown Storage Id '.$event->SecondaryStorageId());
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
|
||||
<?php
|
||||
}
|
||||
if ( ZM_WEB_EVENT_DISK_SPACE ) {
|
||||
$disk_space_total += $event->DiskSpace();
|
||||
?>
|
||||
<td class="colDiskSpace"><?php echo human_filesize($event->DiskSpace()) ?></td>
|
||||
<?php
|
||||
}
|
||||
if ( ZM_WEB_LIST_THUMBS ) {
|
||||
echo '<td class="colThumbnail zoom">';
|
||||
$imgSrc = $event->getThumbnailSrc(array(),'&');
|
||||
$streamSrc = $event->getStreamSrc(array(
|
||||
'mode'=>'jpeg', 'scale'=>$scale, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'replay'=>'single', 'rate'=>'400'), '&');
|
||||
|
||||
$imgHtml = '<img id="thumbnail'.$event->Id().'" src="'.$imgSrc.'" alt="'. validHtmlStr('Event '.$event->Id()) .'" style="width:'. validInt($event->ThumbnailWidth()) .'px;height:'. validInt($event->ThumbnailHeight()).'px;" stream_src="'.$streamSrc.'" still_src="'.$imgSrc.'"/>';
|
||||
echo '<a href="?view=event&eid='. $event->Id().$filterQuery.$sortQuery.'&page=1">'.$imgHtml.'</a>';
|
||||
echo '</td>';
|
||||
} // end if ZM_WEB_LIST_THUMBS
|
||||
?>
|
||||
</tr>
|
||||
<?php
|
||||
} # end foreach row
|
||||
?>
|
||||
<!-- Row data populated via Ajax -->
|
||||
</tbody>
|
||||
<?php
|
||||
} # end if $results
|
||||
if ( ZM_WEB_EVENT_DISK_SPACE ) {
|
||||
?>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="11">Totals:</td>
|
||||
<?php
|
||||
if ( count($storage_areas)>1 ) {
|
||||
?>
|
||||
<td class="colStorage"></td>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<td class="colDiskSpace"><?php echo human_filesize($disk_space_total) ?></td>
|
||||
<?php
|
||||
if ( ZM_WEB_LIST_THUMBS ) {
|
||||
?>
|
||||
<td></td>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -485,6 +485,10 @@ if ( ZM_OPT_MESSAGE ) {
|
|||
<label for="Concurrent"><?php echo translate('ConcurrentFilter') ?></label>
|
||||
<input type="checkbox" id="filter[Concurrent]" name="filter[Concurrent]" value="1"<?php if ( $filter->Concurrent() ) { ?> checked="checked"<?php } ?> data-on-click-this="updateButtons"/>
|
||||
</p>
|
||||
<p>
|
||||
<label for="LockRows"><?php echo translate('FilterLockRows') ?></label>
|
||||
<input type="checkbox" id="filter[LockRows]" name="filter[LockRows]" value="1"<?php if ( $filter->LockRows() ) { ?> checked="checked"<?php } ?> data-on-click-this="updateButtons"/>
|
||||
</p>
|
||||
</div>
|
||||
<hr/>
|
||||
<div id="contentButtons">
|
||||
|
|
|
@ -61,7 +61,7 @@ function processRows(rows) {
|
|||
if ( canEditMonitors ) row.Monitor = '<a href="?view=monitor&mid=' + mid + '">' + row.Monitor + '</a>';
|
||||
if ( canEditEvents ) row.Cause = '<a href="#" title="' + row.Notes + '" class="eDetailLink" data-eid="' + eid + '">' + row.Cause + '</a>';
|
||||
if ( row.Notes.indexOf('detected:') >= 0 ) {
|
||||
row.Cause = row.Cause + '<a href="#?view=image&eid=' + eid + '&fid=objdetect"><div class="small text-nowrap text-muted"><u>' + row.Notes + '</u></div></a>';
|
||||
row.Cause = row.Cause + '<a href="?view=image&eid=' + eid + '&fid=objdetect"><div class="small text-nowrap text-muted"><u>' + row.Notes + '</u></div></a>';
|
||||
} else if ( row.Notes != 'Forced Web: ' ) {
|
||||
row.Cause = row.Cause + '<br/><div class="small text-nowrap text-muted">' + row.Notes + '</div>';
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ function manageDelConfirmModalBtns() {
|
|||
$j.getJSON(thisUrl + '?request=events&task=delete&eids[]='+selections.join('&eids[]='))
|
||||
.done( function(data) {
|
||||
$j('#eventTable').bootstrapTable('refresh');
|
||||
window.location.reload(true);
|
||||
$j('#deleteConfirm').modal('hide');
|
||||
})
|
||||
.fail(logAjaxFail);
|
||||
});
|
||||
|
@ -238,7 +238,6 @@ function initPage() {
|
|||
$j.getJSON(thisUrl + '?request=events&task=archive&eids[]='+selections.join('&eids[]='))
|
||||
.done( function(data) {
|
||||
$j('#eventTable').bootstrapTable('refresh');
|
||||
window.location.reload(true);
|
||||
})
|
||||
.fail(logAjaxFail);
|
||||
});
|
||||
|
@ -257,11 +256,8 @@ function initPage() {
|
|||
$j.getJSON(thisUrl + '?request=events&task=unarchive&eids[]='+selections.join('&eids[]='))
|
||||
.done( function(data) {
|
||||
$j('#eventTable').bootstrapTable('refresh');
|
||||
window.location.reload(true);
|
||||
})
|
||||
.fail(logAjaxFail);
|
||||
|
||||
//window.location.reload(true);
|
||||
});
|
||||
|
||||
// Manage the EDIT button
|
||||
|
@ -321,13 +317,6 @@ function initPage() {
|
|||
$j('#deleteConfirm').modal('show');
|
||||
});
|
||||
|
||||
// Manage the eventdetail links in the events list
|
||||
$j(".eDetailLink").click(function(evt) {
|
||||
evt.preventDefault();
|
||||
var eid = $j(this).data('eid');
|
||||
getEventDetailModal(eid);
|
||||
});
|
||||
|
||||
// Update table links each time after new data is loaded
|
||||
table.on('post-body.bs.table', function(data) {
|
||||
// Manage the eventdetail links in the events list
|
||||
|
@ -343,6 +332,7 @@ function initPage() {
|
|||
table.find("tr td:nth-child(" + (thumb_ndx+1) + ")").addClass('colThumbnail zoom');
|
||||
});
|
||||
|
||||
table.bootstrapTable('resetSearch');
|
||||
// The table is initially given a hidden style, so now that we are done rendering, show it
|
||||
table.show();
|
||||
}
|
||||
|
|
|
@ -74,9 +74,7 @@ function validateForm(form) {
|
|||
|
||||
function updateButtons(element) {
|
||||
var form = element.form;
|
||||
if ( element.type == 'checkbox' && element.checked ) {
|
||||
form.elements['executeButton'].disabled = false;
|
||||
} else {
|
||||
|
||||
var canExecute = false;
|
||||
if ( form.elements['filter[AutoArchive]'] && form.elements['filter[AutoArchive]'].checked ) {
|
||||
canExecute = true;
|
||||
|
@ -102,7 +100,6 @@ function updateButtons(element) {
|
|||
canExecute = true;
|
||||
}
|
||||
form.elements['executeButton'].disabled = !canExecute;
|
||||
}
|
||||
if ( form.elements['filter[Name]'].value ) {
|
||||
form.elements['Save'].disabled = false;
|
||||
form.elements['SaveAs'].disabled = false;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var ZM_OPT_USE_GEOLOCATION = '<?php echo ZM_OPT_USE_GEOLOCATION ?>';
|
||||
var ZM_OPT_USE_GEOLOCATION = '<?php echo ZM_OPT_USE_GEOLOCATION ?>' == '1' ? true : false;
|
||||
<?php
|
||||
if ( ZM_OPT_USE_GEOLOCATION ) {
|
||||
echo 'var ZM_OPT_GEOLOCATION_TILE_PROVIDER=\''.ZM_OPT_GEOLOCATION_TILE_PROVIDER.'\''.PHP_EOL;
|
||||
|
|
|
@ -1,128 +0,0 @@
|
|||
<?php
|
||||
//
|
||||
// ZoneMinder web events view file, $Date$, $Revision$
|
||||
// Copyright (C) 2001-2008 Philip Coombes
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canView('Events') || (!empty($_REQUEST['execute']) && !canEdit('Events')) ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
require_once('includes/Event.php');
|
||||
require_once('includes/Filter.php');
|
||||
|
||||
$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'] ) {
|
||||
$user_monitor_ids = ' M.Id in ('.$user['MonitorIds'].')';
|
||||
$eventsSql .= $user_monitor_ids;
|
||||
} else {
|
||||
$eventsSql .= ' 1';
|
||||
}
|
||||
|
||||
$filter = isset($_REQUEST['filter_id']) ? new ZM\Filter($_REQUEST['filter_id']) : new ZM\Filter();
|
||||
if ( isset($_REQUEST['filter'])) {
|
||||
$filter->set($_REQUEST['filter']);
|
||||
}
|
||||
|
||||
parseSort();
|
||||
|
||||
$filterQuery = $filter->querystring();
|
||||
|
||||
xhtmlHeaders(__FILE__, translate('Events'));
|
||||
getBodyTopHTML();
|
||||
|
||||
?>
|
||||
<?php echo getNavBarHTML() ?>
|
||||
<div id="page" class="container-fluid p-3">
|
||||
<!-- Toolbar button placement and styling handled by bootstrap-tables -->
|
||||
<div id="toolbar">
|
||||
<button id="backBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Back') ?>" disabled><i class="fa fa-arrow-left"></i></button>
|
||||
<button id="refreshBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Refresh') ?>" ><i class="fa fa-refresh"></i></button>
|
||||
<button id="tlineBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('ShowTimeline') ?>" ><i class="fa fa-history"></i></button>
|
||||
<button id="filterBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Filter') ?>"><i class="fa fa-filter"></i></button>
|
||||
<button id="viewBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('View') ?>" disabled><i class="fa fa-binoculars"></i></button>
|
||||
<button id="archiveBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Archive') ?>" disabled><i class="fa fa-archive"></i></button>
|
||||
<button id="unarchiveBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Unarchive') ?>" disabled><i class="fa fa-file-archive-o"></i></button>
|
||||
<button id="editBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Edit') ?>" disabled><i class="fa fa-pencil"></i></button>
|
||||
<button id="exportBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Export') ?>" disabled><i class="fa fa-external-link"></i></button>
|
||||
<button id="downloadBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('DownloadVideo') ?>" disabled><i class="fa fa-download"></i></button>
|
||||
<button id="deleteBtn" class="btn btn-danger" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Delete') ?>" disabled><i class="fa fa-trash"></i></button>
|
||||
</div>
|
||||
|
||||
<!-- Table styling handled by bootstrap-tables -->
|
||||
<div class="row justify-content-center">
|
||||
<table
|
||||
id="eventTable"
|
||||
data-locale="<?php echo i18n() ?>"
|
||||
data-side-pagination="server"
|
||||
data-ajax="ajaxRequest"
|
||||
data-pagination="true"
|
||||
data-show-pagination-switch="true"
|
||||
data-page-list="[10, 25, 50, 100, 200, All]"
|
||||
data-search="true"
|
||||
data-cookie="true"
|
||||
data-cookie-id-table="zmEventsTable"
|
||||
data-cookie-expire="2y"
|
||||
data-click-to-select="true"
|
||||
data-remember-order="true"
|
||||
data-show-columns="true"
|
||||
data-show-export="true"
|
||||
data-uncheckAll="true"
|
||||
data-toolbar="#toolbar"
|
||||
data-show-fullscreen="true"
|
||||
data-click-to-select="true"
|
||||
data-maintain-meta-data="true"
|
||||
data-mobile-responsive="true"
|
||||
data-buttons-class="btn btn-normal"
|
||||
data-show-jump-to="true"
|
||||
data-show-refresh="true"
|
||||
class="table-sm table-borderless"
|
||||
style="display:none;"
|
||||
>
|
||||
<thead>
|
||||
<!-- Row styling is handled by bootstrap-tables -->
|
||||
<tr>
|
||||
<th data-sortable="false" data-field="toggleCheck" data-checkbox="true"></th>
|
||||
<th data-sortable="true" data-field="Id"><?php echo translate('Id') ?></th>
|
||||
<th data-sortable="true" data-field="Name"><?php echo translate('Name') ?></th>
|
||||
<th data-sortable="true" data-field="Archived"><?php echo translate('Archived') ?></th>
|
||||
<th data-sortable="true" data-field="Emailed"><?php echo translate('Emailed') ?></th>
|
||||
<th data-sortable="true" data-field="Monitor"><?php echo translate('Monitor') ?></th>
|
||||
<th data-sortable="true" data-field="Cause"><?php echo translate('Cause') ?></th>
|
||||
<th data-sortable="true" data-field="StartTime"><?php echo translate('AttrStartTime') ?></th>
|
||||
<th data-sortable="true" data-field="EndTime"><?php echo translate('AttrEndTime') ?></th>
|
||||
<th data-sortable="true" data-field="Length"><?php echo translate('Duration') ?></th>
|
||||
<th data-sortable="true" data-field="Frames"><?php echo translate('Frames') ?></th>
|
||||
<th data-sortable="true" data-field="AlarmFrames"><?php echo translate('AlarmBrFrames') ?></th>
|
||||
<th data-sortable="true" data-field="TotScore"><?php echo translate('TotalBrScore') ?></th>
|
||||
<th data-sortable="true" data-field="AvgScore"><?php echo translate('AvgBrScore') ?></th>
|
||||
<th data-sortable="true" data-field="MaxScore"><?php echo translate('MaxBrScore') ?></th>
|
||||
<th data-sortable="false" data-field="Storage"><?php echo translate('Storage') ?></th>
|
||||
<th data-sortable="true" data-field="DiskSpace"><?php echo translate('DiskSpace') ?></th>
|
||||
<th data-sortable="false" data-field="Thumbnail"><?php echo translate('Thumbnail') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<!-- Row data populated via Ajax -->
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php xhtmlFooter() ?>
|
|
@ -279,17 +279,23 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*', GLOB_ONLYDIR)) as
|
|||
<tbody>
|
||||
<?php
|
||||
foreach( ZM\Storage::find( null, array('order'=>'lower(Name)') ) as $Storage ) {
|
||||
$filter = new ZM\Filter();
|
||||
$filter->addTerm(array('attr'=>'StorageId','op'=>'=','val'=>$Storage->Id()));
|
||||
if ( $user['MonitorIds'] ) {
|
||||
$filter = $filter->addTerm(array('cnj'=>'and', 'attr'=>'MonitorId', 'op'=>'IN', 'val'=>$user['MonitorIds']));
|
||||
}
|
||||
|
||||
$str_opt = 'class="storageCol" data-sid="'.$Storage->Id().'"';
|
||||
?>
|
||||
<tr>
|
||||
<td class="colId"><?php echo makeLink('#', validHtmlStr($Storage->Id()), $canEdit, $str_opt ) ?></td>
|
||||
<td class="colName"><?php echo makeLink('#', validHtmlStr($Storage->Name()), $canEdit, $str_opt ) ?></td>
|
||||
<td class="colPath"><?php echo makeLink('#', validHtmlStr($Storage->Path()), $canEdit, $str_opt ) ?></td>
|
||||
<td class="colType"><?php echo makeLink('#', validHtmlStr($Storage->Type()), $canEdit, $str_opt ) ?></td>
|
||||
<td class="colScheme"><?php echo makeLink('#', validHtmlStr($Storage->Scheme()), $canEdit, $str_opt ) ?></td>
|
||||
<td class="colServer"><?php echo makeLink('#', validHtmlStr($Storage->Server()->Name()), $canEdit, $str_opt ) ?></td>
|
||||
<td class="colId"><?php echo makeLink('#', validHtmlStr($Storage->Id()), $canEdit, $str_opt) ?></td>
|
||||
<td class="colName"><?php echo makeLink('#', validHtmlStr($Storage->Name()), $canEdit, $str_opt) ?></td>
|
||||
<td class="colPath"><?php echo makeLink('#', validHtmlStr($Storage->Path()), $canEdit, $str_opt) ?></td>
|
||||
<td class="colType"><?php echo makeLink('#', validHtmlStr($Storage->Type()), $canEdit, $str_opt) ?></td>
|
||||
<td class="colScheme"><?php echo makeLink('#', validHtmlStr($Storage->Scheme()), $canEdit, $str_opt) ?></td>
|
||||
<td class="colServer"><?php echo makeLink('#', validHtmlStr($Storage->Server()->Name()), $canEdit, $str_opt) ?></td>
|
||||
<td class="colDiskSpace"><?php echo human_filesize($Storage->disk_used_space()) . ' of ' . human_filesize($Storage->disk_total_space()) ?></td>
|
||||
<td class="ColEvents"><?php echo $Storage->EventCount().' using '.human_filesize($Storage->event_disk_space()) ?></td>
|
||||
<td class="ColEvents"><?php echo makeLink('?view=events'.$filter->querystring(), $Storage->EventCount().' using '.human_filesize($Storage->event_disk_space()) ); ?></td>
|
||||
<td class="colMark"><input type="checkbox" name="markIds[]" value="<?php echo $Storage->Id() ?>" data-on-click-this="configureDeleteButton"<?php if ( $Storage->EventCount() or !$canEdit ) { ?> disabled="disabled"<?php } ?><?php echo $Storage->EventCount() ? ' title="Can\'t delete as long as there are events stored here."' : ''?>/></td>
|
||||
</tr>
|
||||
<?php } #end foreach Server ?>
|
||||
|
@ -302,13 +308,12 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*', GLOB_ONLYDIR)) as
|
|||
</form>
|
||||
|
||||
<?php
|
||||
} else if ($tab == 'API') {
|
||||
} else if ( $tab == 'API' ) {
|
||||
|
||||
$apiEnabled = dbFetchOne("SELECT Value FROM Config WHERE Name='ZM_OPT_USE_API'");
|
||||
if ($apiEnabled['Value']!='1') {
|
||||
echo "<div class='errorText'>APIs are disabled. To enable, please turn on OPT_USE_API in Options->System</div>";
|
||||
}
|
||||
else {
|
||||
$apiEnabled = dbFetchOne('SELECT Value FROM Config WHERE Name=\'ZM_OPT_USE_API\'');
|
||||
if ( $apiEnabled['Value'] != '1' ) {
|
||||
echo '<div class="errorText">APIs are disabled. To enable, please turn on OPT_USE_API in Options->System</div>';
|
||||
} else {
|
||||
?>
|
||||
|
||||
<form name="userForm" method="post" action="?">
|
||||
|
|
Loading…
Reference in New Issue