Merge branch 'master' into include_fs_config_in_api_config
commit
24ceb75936
|
@ -0,0 +1,26 @@
|
|||
# Configuration for probot-stale - https://github.com/probot/stale
|
||||
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- "Under Review"
|
||||
|
||||
# Set to true to ignore issues in a milestone (defaults to false)
|
||||
exemptMilestones: true
|
||||
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
|
@ -36,8 +36,8 @@ env:
|
|||
- SMPFLAGS=-j4
|
||||
matrix:
|
||||
- OS=el DIST=7
|
||||
- OS=fedora DIST=26 DOCKER_REPO=knnniggett/packpack
|
||||
- OS=fedora DIST=27 DOCKER_REPO=knnniggett/packpack
|
||||
- OS=fedora DIST=28 DOCKER_REPO=knnniggett/packpack
|
||||
- OS=ubuntu DIST=trusty
|
||||
- OS=ubuntu DIST=xenial
|
||||
- OS=ubuntu DIST=trusty ARCH=i386
|
||||
|
|
|
@ -559,7 +559,7 @@ CREATE TABLE `Servers` (
|
|||
`Name` varchar(64) NOT NULL default '',
|
||||
`State_Id` int(10) unsigned,
|
||||
`Status` enum('Unknown','NotRunning','Running') NOT NULL default 'Unknown',
|
||||
`Load` DECIMAL(5,1),
|
||||
`CpuLoad` DECIMAL(5,1) default NULL,
|
||||
`TotalMem` bigint unsigned default null,
|
||||
`FreeMem` bigint unsigned default null,
|
||||
`TotalSwap` bigint unsigned default null,
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
DROP TABLE IF EXISTS `Monitor_Status`;
|
||||
CREATE TABLE `Monitor_Status` (
|
||||
`MonitorId` int(10) unsigned NOT NULL,
|
||||
`Status` enum('Unknown','NotRunning','Running','Connected','Signal') NOT NULL default 'Unknown',
|
||||
`CaptureFPS` DECIMAL(10,2) NOT NULL default 0,
|
||||
`AnalysisFPS` DECIMAL(5,2) NOT NULL default 0,
|
||||
PRIMARY KEY (`MonitorId`)
|
||||
) ENGINE=MEMORY;
|
||||
|
||||
SET SESSION sql_mode='NO_AUTO_VALUE_ON_ZERO';
|
||||
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*) FROM Storage WHERE Name = 'Default' AND Id=0 AND Path='/var/cache/zoneminder/events'
|
||||
) > 0,
|
||||
"SELECT 'Default Storage Area already exists.'",
|
||||
"INSERT INTO Storage (Id,Name,Path,Scheme,ServerId) VALUES (0,'Default','/var/cache/zoneminder/events','Medium',NULL)"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
|
@ -3,6 +3,11 @@ What's New
|
|||
|
||||
1. See the ZoneMinder release notes for a list of new features:
|
||||
https://github.com/ZoneMinder/zoneminder/releases
|
||||
|
||||
2. The contents of the ZoneMinder Apache config file have changed. In
|
||||
addition, this ZoneMinder package now requires you to manually symlink the
|
||||
ZoneMinder Apache config file. See new install step 6 and upgrade step 3
|
||||
below for details.
|
||||
|
||||
New installs
|
||||
============
|
||||
|
|
|
@ -4,6 +4,11 @@ What's New
|
|||
1. See the ZoneMinder release notes for a list of new features:
|
||||
https://github.com/ZoneMinder/zoneminder/releases
|
||||
|
||||
2. The contents of the ZoneMinder Apache config file have changed. In
|
||||
addition, this ZoneMinder package now requires you to manually symlink the
|
||||
ZoneMinder Apache config file. See new install step 6 and upgrade step 3
|
||||
below for details.
|
||||
|
||||
New installs
|
||||
============
|
||||
|
||||
|
@ -80,7 +85,7 @@ New installs
|
|||
When in doubt, proceed with the default:
|
||||
|
||||
sudo ln -s /etc/zm/www/zoneminder.conf /etc/httpd/conf.d/
|
||||
sudo dnf install mod_ssl
|
||||
sudo yum install mod_ssl
|
||||
|
||||
7. Now start the web server:
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
%global _hardened_build 1
|
||||
|
||||
Name: zoneminder
|
||||
Version: 1.31.43
|
||||
Version: 1.31.44
|
||||
Release: 1%{?dist}
|
||||
Summary: A camera monitoring and analysis tool
|
||||
Group: System Environment/Daemons
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Viewing Monitors
|
||||
================
|
||||
|
||||
ZoneMinder allows you to view a live feed of your configured monitors. Once can access this view by clicking on the "Name" column of any of the monitors
|
||||
ZoneMinder allows you to view a live feed of your configured monitors. One can access this view by clicking on the "Name" column of any of the monitors
|
||||
|
||||
.. image:: images/viewmonitor-main.png
|
||||
:width: 500px
|
||||
|
|
|
@ -53,6 +53,7 @@ use HTTP::Cookies;
|
|||
my $ChannelID = 1; # Usually...
|
||||
my $DefaultFocusSpeed = 50; # Should be between 1 and 100
|
||||
my $DefaultIrisSpeed = 50; # Should be between 1 and 100
|
||||
my ($user,$pass,$host,$port);
|
||||
|
||||
sub open {
|
||||
my $self = shift;
|
||||
|
@ -65,7 +66,6 @@ sub open {
|
|||
#
|
||||
# Extract the username/password host/port from ControlAddress
|
||||
#
|
||||
my ($user,$pass,$host,$port);
|
||||
if ( $self->{Monitor}{ControlAddress} =~ /^([^:]+):([^@]+)@(.+)/ ) { # user:pass@host...
|
||||
$user = $1;
|
||||
$pass = $2;
|
||||
|
@ -126,6 +126,8 @@ sub PutCmd {
|
|||
Control Device should be set to \"$1\".
|
||||
Control Device currently set to \"$self->{Monitor}{ControlDevice}\".");
|
||||
$self->{Monitor}{ControlDevice} = $1;
|
||||
$self->{UA}->credentials("$host:$port", $self->{Monitor}{ControlDevice}, $user, $pass);
|
||||
return PutCmd($self,$cmd,$content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,9 +108,18 @@ sub zmDbConnect {
|
|||
, $Config{ZM_DB_PASS}
|
||||
);
|
||||
};
|
||||
Error("Error reconnecting to db: errstr:$DBI::errstr error val:$@") if (! $dbh) or $@;
|
||||
$dbh->trace(0) if $dbh;
|
||||
}
|
||||
if ( !$dbh or $@ ) {
|
||||
Error("Error reconnecting to db: errstr:$DBI::errstr error val:$@");
|
||||
} else {
|
||||
$dbh->{AutoCommit} = 1;
|
||||
Fatal('Can\'t set AutoCommit on in database connection')
|
||||
unless $dbh->{AutoCommit};
|
||||
$dbh->{mysql_auto_reconnect} = 1;
|
||||
Fatal('Can\'t set mysql_auto_reconnect on in database connection')
|
||||
unless $dbh->{mysql_auto_reconnect};
|
||||
$dbh->trace( 0 );
|
||||
} # end if success connecting
|
||||
} # end if ! connected
|
||||
return $dbh;
|
||||
} # end sub zmDbConnect
|
||||
|
||||
|
|
|
@ -602,7 +602,7 @@ Debug("Files to move @files");
|
|||
die "Unable to add key for $filename";
|
||||
}
|
||||
my $duration = time - $starttime;
|
||||
Debug("PUT to S3 " . Number::Bytes::Human::format_bytes($size) . " in $duration seconds = " . Number::Bytes::Human::format_bytes($size/$duration) . "/sec");
|
||||
Debug("PUT to S3 " . Number::Bytes::Human::format_bytes($size) . " in $duration seconds = " . Number::Bytes::Human::format_bytes($duration?$size/$duration:$size) . '/sec');
|
||||
} # end foreach file.
|
||||
|
||||
$moved = 1;
|
||||
|
|
|
@ -307,7 +307,7 @@ sub Sql {
|
|||
if ( $self->{AutoMessage} ) {
|
||||
# Include all events, including events that are still ongoing
|
||||
# and have no EndTime yet
|
||||
$sql .= ' AND ( '.$self->{Sql}.' )';
|
||||
$sql .= ' WHERE ( '.$self->{Sql}.' )';
|
||||
} else {
|
||||
# Only include closed events (events with valid EndTime)
|
||||
$sql .= ' WHERE (E.EndTime IS NOT NULL) AND ( '.$self->{Sql}.' )';
|
||||
|
|
|
@ -198,6 +198,7 @@ sub initialise( @ ) {
|
|||
my $this = shift;
|
||||
my %options = @_;
|
||||
|
||||
$this->{hasTerm} = -t STDERR;
|
||||
$this->{id} = $options{id} if defined($options{id});
|
||||
|
||||
$this->{logPath} = $options{logPath} if defined($options{logPath});
|
||||
|
@ -245,7 +246,8 @@ sub initialise( @ ) {
|
|||
$tempSyslogLevel = $level if defined($level = $this->getTargettedEnv('LOG_LEVEL_SYSLOG'));
|
||||
|
||||
if ( $Config{ZM_LOG_DEBUG} ) {
|
||||
foreach my $target ( split( /\|/, $Config{ZM_LOG_DEBUG_TARGET} ) ) {
|
||||
# Splitting on an empty string doesn't return an empty string, it returns an empty array
|
||||
foreach my $target ( $Config{ZM_LOG_DEBUG_TARGET} ? split(/\|/, $Config{ZM_LOG_DEBUG_TARGET}) : '' ) {
|
||||
if ( $target eq $this->{id}
|
||||
|| $target eq '_'.$this->{id}
|
||||
|| $target eq $this->{idRoot}
|
||||
|
@ -278,6 +280,9 @@ sub initialise( @ ) {
|
|||
|
||||
$this->{initialised} = !undef;
|
||||
|
||||
# this function can get called on a previously initialized log Object, so clean any sth's
|
||||
$this->{sth} = undef;
|
||||
|
||||
Debug( 'LogOpts: level='.$codes{$this->{level}}
|
||||
.'/'.$codes{$this->{effectiveLevel}}
|
||||
.', screen='.$codes{$this->{termLevel}}
|
||||
|
@ -319,6 +324,8 @@ sub reinitialise {
|
|||
my $screenLevel = $this->termLevel();
|
||||
$this->termLevel(NOLOG);
|
||||
$this->termLevel($screenLevel) if $screenLevel > NOLOG;
|
||||
|
||||
$this->{sth} = undef;
|
||||
}
|
||||
|
||||
# Prevents undefined logging levels
|
||||
|
@ -392,6 +399,12 @@ sub level {
|
|||
|
||||
# ICON: I am remarking this out because I don't see the point of having an effective level, if we are just going to set it to level.
|
||||
#$this->{effectiveLevel} = $this->{level} if ( $this->{level} > $this->{effectiveLevel} );
|
||||
# ICON: The point is that LOG_DEBUG can be set either in db or in env var and will get passed in here.
|
||||
# So this will turn on debug, even if not output has Debug level turned on. I think it should be the other way around
|
||||
|
||||
# ICON: Let's try this line instead. effectiveLevel is 1 DEBUG from above, but LOG_DEBUG is off, then $this->level will be 0, and
|
||||
# so effectiveLevel will become 0
|
||||
$this->{effectiveLevel} = $this->{level} if ( $this->{level} < $this->{effectiveLevel} );
|
||||
}
|
||||
return $this->{level};
|
||||
}
|
||||
|
@ -429,54 +442,10 @@ sub databaseLevel {
|
|||
if ( $this->{databaseLevel} != $databaseLevel ) {
|
||||
if ( $databaseLevel > NOLOG and $this->{databaseLevel} <= NOLOG ) {
|
||||
if ( !$this->{dbh} ) {
|
||||
my $socket;
|
||||
my ( $host, $portOrSocket ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ );
|
||||
|
||||
if ( defined($portOrSocket) ) {
|
||||
if ( $portOrSocket =~ /^\// ) {
|
||||
$socket = ';mysql_socket='.$portOrSocket;
|
||||
} else {
|
||||
$socket = ';host='.$host.';port='.$portOrSocket;
|
||||
}
|
||||
} else {
|
||||
$socket = ';host='.$Config{ZM_DB_HOST};
|
||||
}
|
||||
my $sslOptions = '';
|
||||
if ( $Config{ZM_DB_SSL_CA_CERT} ) {
|
||||
$sslOptions = join(';','',
|
||||
'mysql_ssl=1',
|
||||
'mysql_ssl_ca_file='.$Config{ZM_DB_SSL_CA_CERT},
|
||||
'mysql_ssl_client_key='.$Config{ZM_DB_SSL_CLIENT_KEY},
|
||||
'mysql_ssl_client_cert='.$Config{ZM_DB_SSL_CLIENT_CERT}
|
||||
);
|
||||
}
|
||||
$this->{dbh} = DBI->connect( 'DBI:mysql:database='.$Config{ZM_DB_NAME}
|
||||
.$socket.$sslOptions
|
||||
, $Config{ZM_DB_USER}
|
||||
, $Config{ZM_DB_PASS}
|
||||
);
|
||||
if ( !$this->{dbh} ) {
|
||||
$databaseLevel = NOLOG;
|
||||
Error( 'Unable to write log entries to DB, can\'t connect to database '
|
||||
.$Config{ZM_DB_NAME}
|
||||
.' on host '
|
||||
.$Config{ZM_DB_HOST}
|
||||
);
|
||||
} else {
|
||||
$this->{dbh}->{AutoCommit} = 1;
|
||||
Fatal('Can\'t set AutoCommit on in database connection' )
|
||||
unless( $this->{dbh}->{AutoCommit} );
|
||||
$this->{dbh}->{mysql_auto_reconnect} = 1;
|
||||
Fatal('Can\'t set mysql_auto_reconnect on in database connection' )
|
||||
unless( $this->{dbh}->{mysql_auto_reconnect} );
|
||||
$this->{dbh}->trace( 0 );
|
||||
}
|
||||
$this->{dbh} = ZoneMinder::Database::zmDbConnect();
|
||||
}
|
||||
} elsif ( $databaseLevel <= NOLOG && $this->{databaseLevel} > NOLOG ) {
|
||||
if ( $this->{dbh} ) {
|
||||
$this->{dbh}->disconnect();
|
||||
undef($this->{dbh});
|
||||
}
|
||||
undef($this->{dbh});
|
||||
}
|
||||
$this->{databaseLevel} = $databaseLevel;
|
||||
}
|
||||
|
@ -586,29 +555,34 @@ sub logPrint {
|
|||
print(STDERR $message) if $level <= $this->{termLevel};
|
||||
|
||||
if ( $level <= $this->{databaseLevel} ) {
|
||||
if ( ( $this->{dbh} and $this->{dbh}->ping() ) or ( $this->{dbh} = zmDbConnect() ) ) {
|
||||
|
||||
my $sql = 'INSERT INTO Logs ( TimeKey, Component, Pid, Level, Code, Message, File, Line ) VALUES ( ?, ?, ?, ?, ?, ?, ?, NULL )';
|
||||
$this->{sth} = $this->{dbh}->prepare_cached($sql);
|
||||
if ( !$this->{sth} ) {
|
||||
if ( ! ( $this->{dbh} and $this->{dbh}->ping() ) ) {
|
||||
$this->{sth} = undef;
|
||||
if ( ! ( $this->{dbh} = ZoneMinder::Database::zmDbConnect() ) ) {
|
||||
#print(STDERR "Can't log to database: ");
|
||||
$this->{databaseLevel} = NOLOG;
|
||||
Error("Can't prepare log entry '$sql': ".$this->{dbh}->errstr());
|
||||
} else {
|
||||
my $res = $this->{sth}->execute($seconds+($microseconds/1000000.0)
|
||||
, $this->{id}
|
||||
, $$
|
||||
, $level
|
||||
, $code
|
||||
, $string
|
||||
, $this->{fileName}
|
||||
);
|
||||
if ( !$res ) {
|
||||
$this->{databaseLevel} = NOLOG;
|
||||
Error("Can't execute log entry '$sql': ".$this->{dbh}->errstr());
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
print(STDERR "Can't log to database: ");
|
||||
}
|
||||
|
||||
my $sql = 'INSERT INTO Logs ( TimeKey, Component, Pid, Level, Code, Message, File, Line ) VALUES ( ?, ?, ?, ?, ?, ?, ?, NULL )';
|
||||
$this->{sth} = $this->{dbh}->prepare_cached($sql) if ! $this->{sth};
|
||||
if ( !$this->{sth} ) {
|
||||
$this->{databaseLevel} = NOLOG;
|
||||
Error("Can't prepare log entry '$sql': ".$this->{dbh}->errstr());
|
||||
return;
|
||||
}
|
||||
|
||||
my $res = $this->{sth}->execute($seconds+($microseconds/1000000.0)
|
||||
, $this->{id}
|
||||
, $$
|
||||
, $level
|
||||
, $code
|
||||
, $string
|
||||
, $this->{fileName}
|
||||
);
|
||||
if ( !$res ) {
|
||||
$this->{databaseLevel} = NOLOG;
|
||||
Error("Can't execute log entry '$sql': ".$this->{dbh}->errstr());
|
||||
}
|
||||
} # end if doing db logging
|
||||
} # end if level < effectivelevel
|
||||
|
|
|
@ -119,13 +119,13 @@ if ( $command eq 'version' ) {
|
|||
}
|
||||
my $needs_daemon = $command !~ /(?:startup|shutdown|status|check|logrot|version)/;
|
||||
my $daemon = shift @ARGV;
|
||||
if ( $needs_daemon && ! $daemon ) {
|
||||
if ( $needs_daemon && !$daemon ) {
|
||||
print(STDERR "No daemon given\n");
|
||||
pod2usage(-exitstatus => -1);
|
||||
}
|
||||
my @args;
|
||||
|
||||
my $daemon_patt = '('.join( '|', @daemons ).')';
|
||||
my $daemon_patt = '('.join('|', @daemons).')';
|
||||
if ( $needs_daemon ) {
|
||||
if ( $daemon =~ /^${daemon_patt}$/ ) {
|
||||
$daemon = $1;
|
||||
|
@ -139,7 +139,7 @@ foreach my $arg ( @ARGV ) {
|
|||
# Detaint arguments, if they look ok
|
||||
#if ( $arg =~ /^(-{0,2}[\w]+)/ )
|
||||
if ( $arg =~ /^(-{0,2}[\w\/?&=.-]+)$/ ) {
|
||||
push( @args, $1 );
|
||||
push @args, $1;
|
||||
} else {
|
||||
print(STDERR "Bogus argument '$arg' found");
|
||||
exit(-1);
|
||||
|
@ -172,7 +172,7 @@ if ( !$server_up ) {
|
|||
exit();
|
||||
} elsif ( $command ne 'startup' ) {
|
||||
print("Unable to connect to server using socket at " . SOCK_FILE . "\n");
|
||||
exit( -1 );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
# The server isn't there
|
||||
|
@ -210,7 +210,7 @@ if ( ($command eq 'check') && !$daemon ) {
|
|||
|
||||
# The server is there, connect to it
|
||||
CLIENT->autoflush();
|
||||
my $message = join(';', $command, ( $daemon ? $daemon : () ), @args );
|
||||
my $message = join(';', $command, ( $daemon ? $daemon : () ), @args);
|
||||
print(CLIENT $message);
|
||||
shutdown(CLIENT, 1);
|
||||
while( my $line = <CLIENT> ) {
|
||||
|
@ -242,9 +242,20 @@ use constant KILL_DELAY => 60; # seconds to wait between sending TERM and sendin
|
|||
our %cmd_hash;
|
||||
our %pid_hash;
|
||||
our %terminating_processes;
|
||||
our %pids_to_reap;
|
||||
our $zm_terminate = 0;
|
||||
|
||||
sub run {
|
||||
|
||||
# Call this first otherwise stdout/stderror redirects to the pidfile = bad
|
||||
if ( open(my $PID, '>', ZM_PID) ) {
|
||||
print($PID $$);
|
||||
close($PID);
|
||||
} else {
|
||||
# Log not initialized at this point so use die instead
|
||||
die "Can't open pid file at ".ZM_PID."\n";
|
||||
}
|
||||
|
||||
my $fd = 0;
|
||||
while( $fd < POSIX::sysconf(&POSIX::_SC_OPEN_MAX) ) {
|
||||
POSIX::close($fd++);
|
||||
|
@ -252,6 +263,8 @@ sub run {
|
|||
|
||||
setpgrp();
|
||||
|
||||
# dbh got closed with the rest of the fd's above, so need to reconnect.
|
||||
my $dbh = zmDbConnect(1);
|
||||
logInit();
|
||||
|
||||
dPrint(ZoneMinder::Logger::INFO, 'Server starting at '
|
||||
|
@ -259,24 +272,16 @@ sub run {
|
|||
."\n"
|
||||
);
|
||||
|
||||
if ( open(my $PID, '>', ZM_PID) ) {
|
||||
print($PID $$);
|
||||
close($PID);
|
||||
} else {
|
||||
Error("Can't open pid file at " . ZM_PID);
|
||||
}
|
||||
|
||||
# Tell any existing processes to die, wait 1 second between TERM and KILL
|
||||
killAll(1);
|
||||
|
||||
dPrint(ZoneMinder::Logger::INFO, 'Socket should be open at ' .main::SOCK_FILE);
|
||||
my $dbh = zmDbConnect(1);
|
||||
socket(SERVER, PF_UNIX, SOCK_STREAM, 0) or Fatal("Can't open socket: $!");
|
||||
unlink(main::SOCK_FILE) or Error('Unable to unlink ' . main::SOCK_FILE .". Error message was: $!") if -e main::SOCK_FILE;
|
||||
bind(SERVER, $saddr) or Fatal("Can't bind to " . main::SOCK_FILE . ": $!");
|
||||
listen(SERVER, SOMAXCONN) or Fatal("Can't listen: $!");
|
||||
|
||||
$SIG{CHLD} = \&reaper;
|
||||
$SIG{CHLD} = \&chld_sig_handler;
|
||||
$SIG{INT} = \&shutdown_sig_handler;
|
||||
$SIG{TERM} = \&shutdown_sig_handler;
|
||||
$SIG{ABRT} = \&shutdown_sig_handler;
|
||||
|
@ -287,26 +292,19 @@ sub run {
|
|||
my $win = $rin;
|
||||
my $ein = $win;
|
||||
my $timeout = 1;
|
||||
my $Server = undef;
|
||||
my $secs_count = 0;
|
||||
|
||||
if ( $Config{ZM_SERVER_ID} ) {
|
||||
require ZoneMinder::Server;
|
||||
$Server = new ZoneMinder::Server($Config{ZM_SERVER_ID});
|
||||
dPrint(ZoneMinder::Logger::INFO, 'Loading Server record have ' . $$Server{Name});
|
||||
}
|
||||
|
||||
while( !$zm_terminate ) {
|
||||
|
||||
if ( $Config{ZM_SERVER_ID} ) {
|
||||
if ( ! ( $secs_count % 60 ) ) {
|
||||
Debug("Connecting");
|
||||
while ( (!$zm_terminate) and !($dbh and $dbh->ping()) ) {
|
||||
Warning("Not connected to db ($dbh)".($dbh?" ping(".$dbh->ping().")":''). ($DBI::errstr?" errstr($DBI::errstr)":'').' Reconnecting');
|
||||
Warning("Not connected to db ($dbh)".($dbh?' ping('.$dbh->ping().')':''). ($DBI::errstr?" errstr($DBI::errstr)":'').' Reconnecting');
|
||||
$dbh = zmDbConnect();
|
||||
}
|
||||
my @cpuload = CpuLoad();
|
||||
Debug("UPdating Server record @cpuload");
|
||||
Debug("Updating Server record @cpuload");
|
||||
if ( ! defined $dbh->do(q{UPDATE Servers SET Status=?,CpuLoad=?,TotalMem=?,FreeMem=?,TotalSwap=?,FreeSwap=? WHERE Id=?}, undef,
|
||||
'Running', $cpuload[0], &totalmem, &freemem, &totalswap, &freeswap, $Config{ZM_SERVER_ID} ) ) {
|
||||
Error("Failed Updating status of Server record for Id=$Config{ZM_SERVER_ID}".$dbh->errstr());
|
||||
|
@ -315,7 +313,6 @@ sub run {
|
|||
$secs_count += 1;
|
||||
}
|
||||
my $nfound = select(my $rout = $rin, undef, undef, $timeout);
|
||||
Debug("Aftere select $nfound");
|
||||
if ( $nfound > 0 ) {
|
||||
if ( vec($rout, fileno(SERVER), 1) ) {
|
||||
my $paddr = accept(CLIENT, SERVER);
|
||||
|
@ -337,7 +334,7 @@ Debug("Aftere select $nfound");
|
|||
# Do nothing, this is all we're here for
|
||||
dPrint(ZoneMinder::Logger::WARNING, "Already running, ignoring command '$command'\n");
|
||||
} elsif ( $command eq 'shutdown' ) {
|
||||
# Breka out of while loop
|
||||
# Break out of while loop
|
||||
last;
|
||||
} elsif ( $command eq 'check' ) {
|
||||
check($daemon, @args);
|
||||
|
@ -370,10 +367,9 @@ Debug("Aftere select $nfound");
|
|||
#print( "Select timed out\n" );
|
||||
}
|
||||
|
||||
Debug("restartPending");
|
||||
restartPending();
|
||||
Debug("check_for_processes_to_kill");
|
||||
check_for_processes_to_kill();
|
||||
check_for_processes_to_kill() if %terminating_processes;
|
||||
reaper() if %pids_to_reap;
|
||||
|
||||
} # end while
|
||||
|
||||
|
@ -382,7 +378,7 @@ Debug("check_for_processes_to_kill");
|
|||
."\n"
|
||||
);
|
||||
if ( $Config{ZM_SERVER_ID} ) {
|
||||
$dbh = zmDbConnect() if ! $dbh->ping();
|
||||
$dbh = zmDbConnect() if ! ($dbh and $dbh->ping());
|
||||
if ( ! defined $dbh->do(q{UPDATE Servers SET Status='NotRunning' WHERE Id=?}, undef, $Config{ZM_SERVER_ID}) ) {
|
||||
Error("Failed Updating status of Server record for Id=$Config{ZM_SERVER_ID}".$dbh->errstr());
|
||||
}
|
||||
|
@ -391,6 +387,7 @@ Debug("check_for_processes_to_kill");
|
|||
}
|
||||
|
||||
sub cPrint {
|
||||
# One thought here, if no client exists to read these... does it block?
|
||||
if ( fileno(CLIENT) ) {
|
||||
print CLIENT @_
|
||||
}
|
||||
|
@ -399,9 +396,7 @@ sub cPrint {
|
|||
# I think the purpose of this is to echo the logs to the client process so it can then display them.
|
||||
sub dPrint {
|
||||
my $logLevel = shift;
|
||||
if ( fileno(CLIENT) ) {
|
||||
print CLIENT @_
|
||||
}
|
||||
cPrint(@_);
|
||||
if ( $logLevel == ZoneMinder::Logger::DEBUG ) {
|
||||
Debug(@_);
|
||||
} elsif ( $logLevel == ZoneMinder::Logger::INFO ) {
|
||||
|
@ -435,10 +430,12 @@ sub start {
|
|||
|
||||
my $sigset = POSIX::SigSet->new;
|
||||
my $blockset = POSIX::SigSet->new(SIGCHLD);
|
||||
Debug("Blocking SIGCHLD");
|
||||
sigprocmask(SIG_BLOCK, $blockset, $sigset) or Fatal("Can't block SIGCHLD: $!");
|
||||
Debug("forking");
|
||||
# Apparently the child closing the db connection can affect the parent.
|
||||
zmDbDisconnect();
|
||||
if ( my $cpid = fork() ) {
|
||||
|
||||
$dbh = zmDbConnect(1);
|
||||
# This logReinit is required. Not sure why.
|
||||
logReinit();
|
||||
|
||||
|
@ -453,9 +450,10 @@ sub start {
|
|||
|
||||
$cmd_hash{$process->{command}} = $pid_hash{$cpid} = $process;
|
||||
sigprocmask(SIG_SETMASK, $sigset) or Fatal("Can't restore SIGCHLD: $!");
|
||||
Debug("unblocko child");
|
||||
} elsif ( defined($cpid) ) {
|
||||
# Force reconnection to the db.
|
||||
# Child process
|
||||
|
||||
# Force reconnection to the db. $dbh got copied, but isn't really valid anymore.
|
||||
$dbh = zmDbConnect(1);
|
||||
logReinit();
|
||||
|
||||
|
@ -472,7 +470,7 @@ sub start {
|
|||
|
||||
my @good_args;
|
||||
foreach my $arg ( @args ) {
|
||||
# Detaint arguments, if they look ok
|
||||
# Detaint arguments, if they look ok
|
||||
if ( $arg =~ /^(-{0,2}[\w\/?&=.-]+)$/ ) {
|
||||
push @good_args, $1;
|
||||
} else {
|
||||
|
@ -488,8 +486,8 @@ sub start {
|
|||
POSIX::close($fd++);
|
||||
}
|
||||
|
||||
# Child process
|
||||
$SIG{CHLD} = 'DEFAULT';
|
||||
$SIG{HUP} = 'DEFAULT';
|
||||
$SIG{INT} = 'DEFAULT';
|
||||
$SIG{TERM} = 'DEFAULT';
|
||||
$SIG{ABRT} = 'DEFAULT';
|
||||
|
@ -635,15 +633,25 @@ sub shutdown_sig_handler {
|
|||
$zm_terminate = 1;
|
||||
}
|
||||
|
||||
sub reaper {
|
||||
sub chld_sig_handler {
|
||||
my $saved_status = $!;
|
||||
|
||||
# Wait for a child to terminate
|
||||
while ( (my $cpid = waitpid(-1, WNOHANG)) > 0 ) {
|
||||
my $status = $?;
|
||||
$pids_to_reap{$cpid} = { status=>$?, stopped=>time() };
|
||||
} # end while waitpid
|
||||
$SIG{CHLD} = \&chld_sig_handler;
|
||||
$! = $saved_status;
|
||||
}
|
||||
|
||||
sub reaper {
|
||||
foreach my $cpid ( keys %pids_to_reap ) {
|
||||
my $process = $pid_hash{$cpid};
|
||||
Debug("Reaping pricess $cpid");
|
||||
delete $pid_hash{$cpid};
|
||||
my $reap_info = $pids_to_reap{$cpid};
|
||||
my ( $status, $stopped ) = @$reap_info{'status','stopped'};
|
||||
delete $pids_to_reap{$cpid};
|
||||
|
||||
if ( !$process ) {
|
||||
dPrint(ZoneMinder::Logger::INFO, "Can't find child with pid of '$cpid'\n");
|
||||
|
@ -652,7 +660,7 @@ sub reaper {
|
|||
delete $terminating_processes{$$process{command}};
|
||||
delete $$process{term_sent_at};
|
||||
|
||||
$process->{stopped} = time();
|
||||
$process->{stopped} = $stopped;
|
||||
$process->{runtime} = ($process->{stopped}-$process->{started});
|
||||
delete $process->{pid};
|
||||
|
||||
|
@ -705,11 +713,9 @@ sub reaper {
|
|||
} else {
|
||||
delete $cmd_hash{$$process{command}};
|
||||
}
|
||||
} # end while waitpid
|
||||
$SIG{CHLD} = \&reaper;
|
||||
$! = $saved_status;
|
||||
Debug("Leaving reaper");
|
||||
}
|
||||
Debug("Reaping pricess $cpid");
|
||||
} # end foreach pid_to_reap
|
||||
} # end sub reaper
|
||||
|
||||
sub restartPending {
|
||||
# Restart any pending processes, we list them first because cmd_hash may change in foreach
|
||||
|
@ -720,7 +726,6 @@ sub restartPending {
|
|||
start($process->{daemon}, @{$process->{args}});
|
||||
}
|
||||
}
|
||||
Debug("done restartPending");
|
||||
}
|
||||
|
||||
sub shutdownAll {
|
||||
|
@ -730,6 +735,8 @@ sub shutdownAll {
|
|||
send_stop(1, $pid_hash{$pid});
|
||||
}
|
||||
while ( keys %terminating_processes ) {
|
||||
|
||||
reaper() if %pids_to_reap;
|
||||
check_for_processes_to_kill();
|
||||
if ( %terminating_processes ) {
|
||||
Debug("Still " . %terminating_processes . ' to die. sleeping');
|
||||
|
@ -808,7 +815,7 @@ sub status {
|
|||
foreach my $process ( values %cmd_hash ) {
|
||||
if ( $process->{pending} ) {
|
||||
dPrint(ZoneMinder::Logger::DEBUG, "'$process->{command}' pending at "
|
||||
.strftime( '%y/%m/%d %H:%M:%S', localtime($process->{pending}))
|
||||
.strftime('%y/%m/%d %H:%M:%S', localtime($process->{pending}))
|
||||
."\n"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -309,7 +309,7 @@ sub checkFilter {
|
|||
}
|
||||
if ( $Config{ZM_OPT_MESSAGE} && $filter->{AutoMessage} ) {
|
||||
if ( !$event->{Messaged} ) {
|
||||
$delete_ok = undef if !sendMessage($filter, $event);
|
||||
$delete_ok = undef if !sendMessage($filter, $Event);
|
||||
}
|
||||
}
|
||||
if ( $Config{ZM_OPT_UPLOAD} && $filter->{AutoUpload} ) {
|
||||
|
@ -833,7 +833,7 @@ sub sendEmail {
|
|||
|
||||
sub sendMessage {
|
||||
my $filter = shift;
|
||||
my $event = shift;
|
||||
my $Event = shift;
|
||||
|
||||
if ( ! $Config{ZM_FROM_EMAIL} ) {
|
||||
Error('No from email address defined, not sending message');
|
||||
|
@ -846,10 +846,10 @@ sub sendMessage {
|
|||
|
||||
Info('Creating notification message');
|
||||
|
||||
my $subject = substituteTags($Config{ZM_MESSAGE_SUBJECT}, $filter, $event);
|
||||
my $subject = substituteTags($Config{ZM_MESSAGE_SUBJECT}, $filter, $Event);
|
||||
return 0 if !$subject;
|
||||
my @attachments;
|
||||
my $body = substituteTags($Config{ZM_MESSAGE_BODY}, $filter, $event, \@attachments);
|
||||
my $body = substituteTags($Config{ZM_MESSAGE_BODY}, $filter, $Event, \@attachments);
|
||||
return 0 if !$body;
|
||||
|
||||
Info("Sending notification message '$subject'");
|
||||
|
@ -930,11 +930,11 @@ sub sendMessage {
|
|||
my $sql = 'UPDATE Events SET Messaged = 1 WHERE Id = ?';
|
||||
my $sth = $dbh->prepare_cached($sql)
|
||||
or Fatal("Unable toprepare '$sql': ".$dbh->errstr());
|
||||
my $res = $sth->execute($event->{Id})
|
||||
my $res = $sth->execute($Event->{Id})
|
||||
or Fatal("Unable toexecute '$sql': ".$dbh->errstr());
|
||||
|
||||
return 1;
|
||||
}
|
||||
} # end sub sendMessage
|
||||
|
||||
sub executeCommand {
|
||||
my $filter = shift;
|
||||
|
|
|
@ -69,41 +69,44 @@ delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
|
|||
logInit();
|
||||
logSetSignal();
|
||||
|
||||
Info( "Watchdog starting, pausing for ".START_DELAY." seconds\n" );
|
||||
sleep( START_DELAY );
|
||||
Info('Watchdog starting, pausing for '.START_DELAY.' seconds');
|
||||
sleep(START_DELAY);
|
||||
|
||||
my $dbh = zmDbConnect();
|
||||
my $sql = $Config{ZM_SERVER_ID} ? 'SELECT * FROM Monitors WHERE ServerId=?' : 'SELECT * FROM Monitors';
|
||||
my $sth = $dbh->prepare_cached( $sql )
|
||||
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
my $sth = $dbh->prepare_cached($sql)
|
||||
or Fatal("Can't prepare '$sql': ".$dbh->errstr());
|
||||
|
||||
while( 1 ) {
|
||||
|
||||
my $res = $sth->execute( $Config{ZM_SERVER_ID} ? $Config{ZM_SERVER_ID} : () )
|
||||
or Fatal( "Can't execute: ".$sth->errstr() );
|
||||
or Fatal('Can\'t execute: '.$sth->errstr());
|
||||
while( my $monitor = $sth->fetchrow_hashref() ) {
|
||||
my $now = time();
|
||||
next if $monitor->{Function} eq 'None';
|
||||
next if $monitor->{Type} eq 'WebSite';
|
||||
my $now = time();
|
||||
my $restart = 0;
|
||||
if ( zmMemVerify( $monitor ) ) {
|
||||
if ( zmMemVerify($monitor) ) {
|
||||
# Check we have got an image recently
|
||||
my $capture_time = zmGetLastWriteTime( $monitor );
|
||||
my $capture_time = zmGetLastWriteTime($monitor);
|
||||
if ( !defined($capture_time) ) {
|
||||
# Can't read from shared data
|
||||
Debug( "LastWriteTime is not defined." );
|
||||
zmMemInvalidate( $monitor );
|
||||
Debug('LastWriteTime is not defined.');
|
||||
zmMemInvalidate($monitor);
|
||||
next;
|
||||
}
|
||||
Debug( "LastWriteTime is = $capture_time." );
|
||||
Debug("Monitor $$monitor{Id} LastWriteTime is $capture_time.");
|
||||
if ( !$capture_time ) {
|
||||
my $startup_time = zmGetStartupTime( $monitor );
|
||||
my $startup_time = zmGetStartupTime($monitor);
|
||||
if ( $now - $startup_time > $Config{ZM_WATCH_MAX_DELAY} ) {
|
||||
Info( "Restarting capture daemon for ".$monitor->{Name}.", no image since startup. Startup time was $startup_time - now $now > $Config{ZM_WATCH_MAX_DELAY}\n" );
|
||||
Info(
|
||||
"Restarting capture daemon for $$monitor{Name}, no image since startup. ".
|
||||
"Startup time was $startup_time - now $now > $Config{ZM_WATCH_MAX_DELAY}"
|
||||
);
|
||||
$restart = 1;
|
||||
} else {
|
||||
# We can't get the last capture time so can't be sure it's died, it might just be starting up.
|
||||
zmMemInvalidate( $monitor );
|
||||
zmMemInvalidate($monitor);
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
@ -115,44 +118,44 @@ while( 1 ) {
|
|||
: $Config{ZM_WATCH_MAX_DELAY}
|
||||
;
|
||||
my $image_delay = $now-$capture_time;
|
||||
Debug( "Monitor $monitor->{Id} last captured $image_delay seconds ago, max is $max_image_delay\n" );
|
||||
Debug("Monitor $monitor->{Id} last captured $image_delay seconds ago, max is $max_image_delay");
|
||||
if ( $image_delay > $max_image_delay ) {
|
||||
Info( "Restarting capture daemon for "
|
||||
.$monitor->{Name}.", time since last capture $image_delay seconds ($now-$capture_time)\n"
|
||||
Info("Restarting capture daemon for "
|
||||
.$monitor->{Name}.", time since last capture $image_delay seconds ($now-$capture_time)"
|
||||
);
|
||||
$restart = 1;
|
||||
}
|
||||
} # end if ! restart
|
||||
} else {
|
||||
Info( "Restarting capture daemon for ".$monitor->{Name}.", shared data not valid\n" );
|
||||
Info("Restarting capture daemon for $monitor->{Name}, shared data not valid");
|
||||
$restart = 1;
|
||||
}
|
||||
|
||||
if ( $restart ) {
|
||||
# Because zma depends on zmc, and zma can hold the shm in place, preventing zmc from using the space in /dev/shm,
|
||||
# we need to stop zma before restarting zmc.
|
||||
runCommand( "zmdc.pl stop zma -m $$monitor{Id}" ) if $monitor->{Function} ne 'Monitor';
|
||||
runCommand("zmdc.pl stop zma -m $$monitor{Id}") if $monitor->{Function} ne 'Monitor';
|
||||
my $command;
|
||||
if ( $monitor->{Type} eq 'Local' ) {
|
||||
$command = "zmdc.pl restart zmc -d $monitor->{Device}";
|
||||
} else {
|
||||
$command = "zmdc.pl restart zmc -m $monitor->{Id}";
|
||||
}
|
||||
runCommand( $command );
|
||||
runCommand( "zmdc.pl start zma -m $$monitor{Id}" ) if $monitor->{Function} ne 'Monitor';
|
||||
runCommand($command);
|
||||
runCommand("zmdc.pl start zma -m $$monitor{Id}") if $monitor->{Function} ne 'Monitor';
|
||||
} elsif ( $monitor->{Function} ne 'Monitor' ) {
|
||||
# Now check analysis daemon
|
||||
$restart = 0;
|
||||
# Check we have got an image recently
|
||||
my $image_time = zmGetLastReadTime( $monitor );
|
||||
my $image_time = zmGetLastReadTime($monitor);
|
||||
if ( !defined($image_time) ) {
|
||||
# Can't read from shared data
|
||||
$restart = 1;
|
||||
Error("Error reading shared data for $$monitor{Id} $$monitor{Name}\n");
|
||||
Error("Error reading shared data for $$monitor{Id} $$monitor{Name}");
|
||||
} elsif ( !$image_time ) {
|
||||
# We can't get the last capture time so can't be sure it's died.
|
||||
$restart = 1;
|
||||
Error("Last analyse time for $$monitor{Id} $$monitor{Name} was zero.\n");
|
||||
Error("Last analyse time for $$monitor{Id} $$monitor{Name} was zero.");
|
||||
} else {
|
||||
|
||||
my $max_image_delay = ( $monitor->{MaxFPS}
|
||||
|
@ -162,29 +165,29 @@ while( 1 ) {
|
|||
: $Config{ZM_WATCH_MAX_DELAY}
|
||||
;
|
||||
my $image_delay = $now-$image_time;
|
||||
Debug( "Monitor $monitor->{Id} last analysed $image_delay seconds ago, max is $max_image_delay\n" );
|
||||
Debug("Monitor $monitor->{Id} last analysed $image_delay seconds ago, max is $max_image_delay");
|
||||
if ( $image_delay > $max_image_delay ) {
|
||||
Info( "Analysis daemon for $$monitor{Id} $$monitor{Name} needs restarting,"
|
||||
." time since last analysis $image_delay seconds ($now-$image_time)\n"
|
||||
Info("Analysis daemon for $$monitor{Id} $$monitor{Name} needs restarting,"
|
||||
." time since last analysis $image_delay seconds ($now-$image_time)"
|
||||
);
|
||||
$restart = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $restart ) {
|
||||
Info( "Restarting analysis daemon for $$monitor{Id} $$monitor{Name}\n");
|
||||
Info("Restarting analysis daemon for $$monitor{Id} $$monitor{Name}");
|
||||
my $command = 'zmdc.pl restart zma -m '.$monitor->{Id};
|
||||
runCommand( $command );
|
||||
runCommand($command);
|
||||
} # end if restart
|
||||
} # end if check analysis daemon
|
||||
# Prevent open handles building up if we have connect to shared memory
|
||||
zmMemInvalidate( $monitor ); # Close our file handle to the zmc process we are about to end
|
||||
zmMemInvalidate($monitor); # Close our file handle to the zmc process we are about to end
|
||||
} # end foreach monitor
|
||||
|
||||
sleep( $Config{ZM_WATCH_CHECK_INTERVAL} );
|
||||
sleep($Config{ZM_WATCH_CHECK_INTERVAL});
|
||||
} # end while (1)
|
||||
|
||||
Info( "Watchdog exiting\n" );
|
||||
Info("Watchdog exiting");
|
||||
exit();
|
||||
|
||||
1;
|
||||
|
|
|
@ -85,7 +85,10 @@ public:
|
|||
|
||||
bool CanCapture() const { return( capture ); }
|
||||
|
||||
bool SupportsNativeVideo() const { return( (type == FFMPEG_SRC )||(type == REMOTE_SRC)); }
|
||||
bool SupportsNativeVideo() const {
|
||||
return (type == FFMPEG_SRC);
|
||||
//return (type == FFMPEG_SRC )||(type == REMOTE_SRC);
|
||||
}
|
||||
|
||||
virtual int PrimeCapture() { return( 0 ); }
|
||||
virtual int PreCapture()=0;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "zm_db.h"
|
||||
|
||||
MYSQL dbconn;
|
||||
Mutex db_mutex;
|
||||
RecursiveMutex db_mutex;
|
||||
|
||||
bool zmDbConnected = false;
|
||||
|
||||
|
@ -91,15 +91,15 @@ void zmDbClose() {
|
|||
}
|
||||
|
||||
MYSQL_RES * zmDbFetch(const char * query) {
|
||||
if ( ! zmDbConnected ) {
|
||||
if ( !zmDbConnected ) {
|
||||
Error("Not connected.");
|
||||
return NULL;
|
||||
}
|
||||
db_mutex.lock();
|
||||
|
||||
if ( mysql_query(&dbconn, query) ) {
|
||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||
db_mutex.unlock();
|
||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||
return NULL;
|
||||
}
|
||||
Debug(4, "Success running query: %s", query);
|
||||
|
|
|
@ -41,7 +41,7 @@ class zmDbRow {
|
|||
};
|
||||
|
||||
extern MYSQL dbconn;
|
||||
extern Mutex db_mutex;
|
||||
extern RecursiveMutex db_mutex;
|
||||
|
||||
bool zmDbConnect();
|
||||
void zmDbClose();
|
||||
|
|
|
@ -69,7 +69,8 @@ Event::Event(
|
|||
untimedEvent = true;
|
||||
start_time = now;
|
||||
} else if ( start_time.tv_sec > now.tv_sec ) {
|
||||
Error("StartTime in the future %u.%u > %u.%u",
|
||||
Error(
|
||||
"StartTime in the future %u.%u > %u.%u",
|
||||
start_time.tv_sec, start_time.tv_usec, now.tv_sec, now.tv_usec
|
||||
);
|
||||
start_time = now;
|
||||
|
@ -520,7 +521,7 @@ void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *a
|
|||
}
|
||||
} else {
|
||||
//If this is the first frame, we should add a thumbnail to the event directory
|
||||
if ( frames == 1 ) {
|
||||
if ( frames == 1 || score > (int)max_score ) {
|
||||
char snapshot_file[PATH_MAX];
|
||||
snprintf(snapshot_file, sizeof(snapshot_file), "%s/snapshot.jpg", path);
|
||||
WriteFrameImage(image, timestamp, snapshot_file);
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
Group::Group() {
|
||||
Warning("Instantiating default Group Object. Should not happen.");
|
||||
|
@ -33,30 +32,31 @@ Group::Group() {
|
|||
strcpy(name, "Default");
|
||||
}
|
||||
|
||||
Group::Group( MYSQL_ROW &dbrow ) {
|
||||
// The order of columns is: Id, ParentId, Name
|
||||
Group::Group(MYSQL_ROW &dbrow) {
|
||||
unsigned int index = 0;
|
||||
id = atoi( dbrow[index++] );
|
||||
parent_id = dbrow[index] ? atoi( dbrow[index] ): 0; index++;
|
||||
strncpy( name, dbrow[index++], sizeof(name)-1 );
|
||||
id = atoi(dbrow[index++]);
|
||||
parent_id = dbrow[index] ? atoi(dbrow[index]): 0; index++;
|
||||
strncpy(name, dbrow[index++], sizeof(name)-1);
|
||||
}
|
||||
|
||||
/* If a zero or invalid p_id is passed, then the old default path will be assumed. */
|
||||
Group::Group( unsigned int p_id ) {
|
||||
Group::Group(unsigned int p_id) {
|
||||
id = 0;
|
||||
|
||||
if ( p_id ) {
|
||||
char sql[ZM_SQL_SML_BUFSIZ];
|
||||
snprintf( sql, sizeof(sql), "SELECT Id, ParentId, Name FROM Group WHERE Id=%d", p_id );
|
||||
Debug(2,"Loading Group for %d using %s", p_id, sql );
|
||||
snprintf(sql, sizeof(sql), "SELECT Id, ParentId, Name FROM Group WHERE Id=%d", p_id);
|
||||
Debug(2,"Loading Group for %d using %s", p_id, sql);
|
||||
zmDbRow dbrow;
|
||||
if ( ! dbrow.fetch( sql ) ) {
|
||||
Error( "Unable to load group for id %d: %s", p_id, mysql_error( &dbconn ) );
|
||||
if ( !dbrow.fetch(sql) ) {
|
||||
Error("Unable to load group for id %d: %s", p_id, mysql_error(&dbconn));
|
||||
} else {
|
||||
unsigned int index = 0;
|
||||
id = atoi( dbrow[index++] );
|
||||
parent_id = dbrow[index] ? atoi( dbrow[index] ): 0; index++;
|
||||
strncpy( name, dbrow[index++], sizeof(name)-1 );
|
||||
Debug( 1, "Loaded Group area %d '%s'", id, this->Name() );
|
||||
id = atoi(dbrow[index++]);
|
||||
parent_id = dbrow[index] ? atoi(dbrow[index]): 0; index++;
|
||||
strncpy(name, dbrow[index++], sizeof(name)-1);
|
||||
Debug(1, "Loaded Group area %d '%s'", id, this->Name());
|
||||
}
|
||||
}
|
||||
if ( ! id ) {
|
||||
|
|
|
@ -551,7 +551,7 @@ void Logger::logPrint( bool hex, const char * const filepath, const int line, co
|
|||
} else {
|
||||
Level tempDatabaseLevel = mDatabaseLevel;
|
||||
databaseLevel(NOLOG);
|
||||
Error("Can't insert log entry: sql(%s) error(db is locked)", sql);
|
||||
Error("Can't insert log entry: sql(%s) error(db is locked)", logString);
|
||||
databaseLevel(tempDatabaseLevel);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1397,9 +1397,12 @@ bool Monitor::Analyse() {
|
|||
int motion_score = last_motion_score;
|
||||
if ( !(image_count % (motion_frame_skip+1) ) ) {
|
||||
// Get new score.
|
||||
motion_score = DetectMotion( *snap_image, zoneSet );
|
||||
motion_score = DetectMotion(*snap_image, zoneSet);
|
||||
|
||||
Debug( 3, "After motion detection, last_motion_score(%d), new motion score(%d)", last_motion_score, motion_score );
|
||||
Debug(3,
|
||||
"After motion detection, last_motion_score(%d), new motion score(%d)",
|
||||
last_motion_score, motion_score
|
||||
);
|
||||
// Why are we updating the last_motion_score too?
|
||||
last_motion_score = motion_score;
|
||||
}
|
||||
|
@ -1542,15 +1545,16 @@ bool Monitor::Analyse() {
|
|||
} // end if ! event
|
||||
}
|
||||
if ( score ) {
|
||||
if ( (state == IDLE || state == TAPE || state == PREALARM ) ) {
|
||||
if ( Event::PreAlarmCount() >= (alarm_frame_count-1) ) {
|
||||
Info( "%s: %03d - Gone into alarm state", name, image_count );
|
||||
if ( state == IDLE || state == TAPE || state == PREALARM ) {
|
||||
if ( (!pre_event_count) || (Event::PreAlarmCount() >= alarm_frame_count) ) {
|
||||
Info("%s: %03d - Gone into alarm state %u > %u",
|
||||
name, image_count, Event::PreAlarmCount(), alarm_frame_count);
|
||||
shared_data->state = state = ALARM;
|
||||
if ( signal_change || (function != MOCORD && state != ALERT) ) {
|
||||
int pre_index;
|
||||
int pre_event_images = pre_event_count;
|
||||
|
||||
if ( analysis_fps ) {
|
||||
if ( analysis_fps && pre_event_count ) {
|
||||
// If analysis fps is set,
|
||||
// compute the index for pre event images in the dedicated buffer
|
||||
pre_index = pre_event_buffer_count ? image_count%pre_event_buffer_count : 0;
|
||||
|
@ -1563,7 +1567,7 @@ bool Monitor::Analyse() {
|
|||
pre_event_images--;
|
||||
}
|
||||
|
||||
event = new Event( this, *(pre_event_buffer[pre_index].timestamp), cause, noteSetMap );
|
||||
event = new Event(this, *(pre_event_buffer[pre_index].timestamp), cause, noteSetMap);
|
||||
} else {
|
||||
// If analysis fps is not set (analysis performed at capturing framerate),
|
||||
// compute the index for pre event images in the capturing buffer
|
||||
|
@ -1580,7 +1584,7 @@ bool Monitor::Analyse() {
|
|||
pre_event_images--;
|
||||
}
|
||||
|
||||
event = new Event( this, *(image_buffer[pre_index].timestamp), cause, noteSetMap );
|
||||
event = new Event(this, *(image_buffer[pre_index].timestamp), cause, noteSetMap);
|
||||
}
|
||||
shared_data->last_event = event->Id();
|
||||
// lets construct alarm cause. It will contain cause + names of zones alarmed
|
||||
|
@ -2799,19 +2803,21 @@ Monitor::Snapshot *Monitor::getSnapshot() const {
|
|||
return &image_buffer[ shared_data->last_write_index%image_buffer_count ];
|
||||
}
|
||||
|
||||
std::list<Group *> Monitor::Groups() {
|
||||
std::vector<Group *> Monitor::Groups() {
|
||||
// At the moment, only load groups once.
|
||||
if ( ! groups.size() ) {
|
||||
std::string sql = stringtf("SELECT GroupId FROM Groups_Monitors WHERE MonitorId=%d",id);
|
||||
std::string sql = stringtf(
|
||||
"SELECT Id,ParentId,Name FROM Groups WHERE Groups.Id IN "
|
||||
"(SELECT GroupId FROM Groups_Monitors WHERE MonitorId=%d)",id);
|
||||
MYSQL_RES *result = zmDbFetch(sql.c_str());
|
||||
if ( !result ) {
|
||||
Error("Can't load groups: %s", mysql_error(&dbconn));
|
||||
return groups;
|
||||
}
|
||||
int n_groups = mysql_num_rows(result);
|
||||
Debug( 1, "Got %d groups", n_groups );
|
||||
Debug(1, "Got %d groups", n_groups);
|
||||
while ( MYSQL_ROW dbrow = mysql_fetch_row(result) ) {
|
||||
groups.push_back( new Group(dbrow) );
|
||||
groups.push_back(new Group(dbrow));
|
||||
}
|
||||
if ( mysql_errno(&dbconn) ) {
|
||||
Error("Can't fetch row: %s", mysql_error(&dbconn));
|
||||
|
@ -2820,3 +2826,13 @@ std::list<Group *> Monitor::Groups() {
|
|||
}
|
||||
return groups;
|
||||
}
|
||||
|
||||
StringVector Monitor::GroupNames() {
|
||||
StringVector groupnames;
|
||||
for(Group * g: Groups()) {
|
||||
groupnames.push_back(std::string(g->Name()));
|
||||
Debug(1,"Groups: %s", g->Name());
|
||||
}
|
||||
return groupnames;
|
||||
}
|
||||
|
||||
|
|
|
@ -344,7 +344,7 @@ protected:
|
|||
int n_linked_monitors;
|
||||
MonitorLink **linked_monitors;
|
||||
|
||||
std::list<Group *> groups;
|
||||
std::vector<Group *> groups;
|
||||
|
||||
public:
|
||||
explicit Monitor( int p_id );
|
||||
|
@ -506,7 +506,8 @@ public:
|
|||
|
||||
bool DumpSettings( char *output, bool verbose );
|
||||
void DumpZoneImage( const char *zone_string=0 );
|
||||
std::list<Group *> Groups();
|
||||
std::vector<Group *> Groups();
|
||||
StringVector GroupNames();
|
||||
|
||||
static int LoadMonitors(std::string sql, Monitor **&monitors, Purpose purpose); // Returns # of Monitors loaded, 0 on failure.
|
||||
#if ZM_HAS_V4L
|
||||
|
|
|
@ -533,7 +533,7 @@ int RemoteCameraRtsp::CaptureAndRecord(Image &image, timeval recording, char* ev
|
|||
zm_av_packet_unref( &packet );
|
||||
} // end while ! framecomplete and buffer.size()
|
||||
if(frameComplete)
|
||||
return (0);
|
||||
return (1);
|
||||
} /* getFrame() */
|
||||
|
||||
} // end while true
|
||||
|
|
|
@ -95,6 +95,15 @@ bool Mutex::locked() {
|
|||
return( state == EBUSY );
|
||||
}
|
||||
|
||||
RecursiveMutex::RecursiveMutex() {
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
|
||||
if ( pthread_mutex_init(&mMutex, &attr) < 0 )
|
||||
Error("Unable to create pthread mutex: %s", strerror(errno));
|
||||
}
|
||||
|
||||
Condition::Condition( Mutex &mutex ) : mMutex( mutex ) {
|
||||
if ( pthread_cond_init( &mCondition, NULL ) < 0 )
|
||||
throw ThreadException( stringtf( "Unable to create pthread condition: %s", strerror(errno) ) );
|
||||
|
|
|
@ -59,27 +59,34 @@ public:
|
|||
};
|
||||
|
||||
class Mutex {
|
||||
friend class Condition;
|
||||
friend class Condition;
|
||||
|
||||
private:
|
||||
pthread_mutex_t mMutex;
|
||||
private:
|
||||
pthread_mutex_t mMutex;
|
||||
|
||||
public:
|
||||
Mutex();
|
||||
~Mutex();
|
||||
public:
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
private:
|
||||
pthread_mutex_t *getMutex() {
|
||||
return( &mMutex );
|
||||
}
|
||||
private:
|
||||
pthread_mutex_t *getMutex() {
|
||||
return &mMutex;
|
||||
}
|
||||
|
||||
public:
|
||||
int trylock();
|
||||
void lock();
|
||||
void lock( int secs );
|
||||
void lock( double secs );
|
||||
void unlock();
|
||||
bool locked();
|
||||
public:
|
||||
int trylock();
|
||||
void lock();
|
||||
void lock( int secs );
|
||||
void lock( double secs );
|
||||
void unlock();
|
||||
bool locked();
|
||||
};
|
||||
|
||||
class RecursiveMutex : public Mutex {
|
||||
private:
|
||||
pthread_mutex_t mMutex;
|
||||
public:
|
||||
RecursiveMutex();
|
||||
};
|
||||
|
||||
class ScopedMutex {
|
||||
|
|
|
@ -94,26 +94,22 @@ const std::string stringtf( const std::string format, ... )
|
|||
return( tempString );
|
||||
}
|
||||
|
||||
bool startsWith( const std::string &haystack, const std::string &needle )
|
||||
{
|
||||
return( haystack.substr( 0, needle.length() ) == needle );
|
||||
bool startsWith(const std::string &haystack, const std::string &needle) {
|
||||
return( haystack.substr(0, needle.length()) == needle );
|
||||
}
|
||||
|
||||
StringVector split( const std::string &string, const std::string &chars, int limit )
|
||||
{
|
||||
StringVector split(const std::string &string, const std::string &chars, int limit) {
|
||||
StringVector stringVector;
|
||||
std::string tempString = string;
|
||||
std::string::size_type startIndex = 0;
|
||||
std::string::size_type endIndex = 0;
|
||||
|
||||
//Info( "Looking for '%s' in '%s', limit %d", chars.c_str(), string.c_str(), limit );
|
||||
do
|
||||
{
|
||||
do {
|
||||
// Find delimiters
|
||||
endIndex = string.find_first_of( chars, startIndex );
|
||||
//Info( "Got endIndex at %d", endIndex );
|
||||
if ( endIndex > 0 )
|
||||
{
|
||||
if ( endIndex > 0 ) {
|
||||
//Info( "Adding '%s'", string.substr( startIndex, endIndex-startIndex ).c_str() );
|
||||
stringVector.push_back( string.substr( startIndex, endIndex-startIndex ) );
|
||||
}
|
||||
|
@ -121,8 +117,7 @@ StringVector split( const std::string &string, const std::string &chars, int lim
|
|||
break;
|
||||
// Find non-delimiters
|
||||
startIndex = tempString.find_first_not_of( chars, endIndex );
|
||||
if ( limit && (stringVector.size() == (unsigned int)(limit-1)) )
|
||||
{
|
||||
if ( limit && (stringVector.size() == (unsigned int)(limit-1)) ) {
|
||||
stringVector.push_back( string.substr( startIndex ) );
|
||||
break;
|
||||
}
|
||||
|
@ -130,22 +125,21 @@ StringVector split( const std::string &string, const std::string &chars, int lim
|
|||
} while ( startIndex != std::string::npos );
|
||||
//Info( "Finished with %d strings", stringVector.size() );
|
||||
|
||||
return( stringVector );
|
||||
return stringVector;
|
||||
}
|
||||
|
||||
const std::string join(const StringVector &v, const char * delim ) {
|
||||
const std::string join(const StringVector &v, const char * delim=",") {
|
||||
std::stringstream ss;
|
||||
|
||||
for(size_t i = 0; i < v.size(); ++i) {
|
||||
if(i != 0)
|
||||
ss << ",";
|
||||
for (size_t i = 0; i < v.size(); ++i) {
|
||||
if ( i != 0 )
|
||||
ss << delim;
|
||||
ss << v[i];
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
const std::string base64Encode( const std::string &inString )
|
||||
{
|
||||
const std::string base64Encode(const std::string &inString) {
|
||||
static char base64_table[64] = { '\0' };
|
||||
|
||||
if ( !base64_table[0] )
|
||||
|
|
|
@ -17,12 +17,15 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
#define __STDC_FORMAT_MACROS 1
|
||||
#include <cinttypes>
|
||||
#include "zm.h"
|
||||
#include "zm_db.h"
|
||||
#include "zm_zone.h"
|
||||
#include "zm_image.h"
|
||||
#include "zm_monitor.h"
|
||||
|
||||
|
||||
void Zone::Setup(
|
||||
Monitor *p_monitor,
|
||||
int p_id,
|
||||
|
|
49
src/zms.cpp
49
src/zms.cpp
|
@ -74,45 +74,44 @@ int main( int argc, const char *argv[] ) {
|
|||
unsigned int playback_buffer = 0;
|
||||
|
||||
bool nph = false;
|
||||
const char *basename = strrchr( argv[0], '/' );
|
||||
if (basename) //if we found a / lets skip past it
|
||||
const char *basename = strrchr(argv[0], '/');
|
||||
if ( basename ) //if we found a / lets skip past it
|
||||
basename++;
|
||||
else //argv[0] will not always contain the full path, but rather just the script name
|
||||
basename = argv[0];
|
||||
const char *nph_prefix = "nph-";
|
||||
if ( basename && !strncmp( basename, nph_prefix, strlen(nph_prefix) ) ) {
|
||||
if ( basename && !strncmp(basename, nph_prefix, strlen(nph_prefix)) ) {
|
||||
nph = true;
|
||||
}
|
||||
|
||||
zmLoadConfig();
|
||||
|
||||
|
||||
const char *query = getenv( "QUERY_STRING" );
|
||||
const char *query = getenv("QUERY_STRING");
|
||||
if ( query ) {
|
||||
Debug( 1, "Query: %s", query );
|
||||
Debug(1, "Query: %s", query);
|
||||
|
||||
char temp_query[1024];
|
||||
strncpy( temp_query, query, sizeof(temp_query) );
|
||||
strncpy(temp_query, query, sizeof(temp_query));
|
||||
char *q_ptr = temp_query;
|
||||
char *parms[16]; // Shouldn't be more than this
|
||||
int parm_no = 0;
|
||||
while( (parm_no < 16) && (parms[parm_no] = strtok( q_ptr, "&" )) ) {
|
||||
while( (parm_no < 16) && (parms[parm_no] = strtok(q_ptr, "&")) ) {
|
||||
parm_no++;
|
||||
q_ptr = NULL;
|
||||
}
|
||||
|
||||
for ( int p = 0; p < parm_no; p++ ) {
|
||||
char *name = strtok( parms[p], "=" );
|
||||
char *value = strtok( NULL, "=" );
|
||||
char *name = strtok(parms[p], "=");
|
||||
char *value = strtok(NULL, "=");
|
||||
if ( !value )
|
||||
value = (char *)"";
|
||||
if ( !strcmp( name, "source" ) ) {
|
||||
source = !strcmp( value, "event" )?ZMS_EVENT:ZMS_MONITOR;
|
||||
} else if ( !strcmp( name, "mode" ) ) {
|
||||
mode = !strcmp( value, "jpeg" )?ZMS_JPEG:ZMS_MPEG;
|
||||
mode = !strcmp( value, "raw" )?ZMS_RAW:mode;
|
||||
mode = !strcmp( value, "zip" )?ZMS_ZIP:mode;
|
||||
mode = !strcmp( value, "single" )?ZMS_SINGLE:mode;
|
||||
if ( !strcmp(name, "source") ) {
|
||||
source = !strcmp(value, "event")?ZMS_EVENT:ZMS_MONITOR;
|
||||
} else if ( !strcmp(name, "mode") ) {
|
||||
mode = !strcmp(value, "jpeg")?ZMS_JPEG:ZMS_MPEG;
|
||||
mode = !strcmp(value, "raw")?ZMS_RAW:mode;
|
||||
mode = !strcmp(value, "zip")?ZMS_ZIP:mode;
|
||||
mode = !strcmp(value, "single")?ZMS_SINGLE:mode;
|
||||
} else if ( !strcmp( name, "format" ) ) {
|
||||
strncpy( format, value, sizeof(format) );
|
||||
} else if ( !strcmp( name, "monitor" ) ) {
|
||||
|
@ -182,32 +181,32 @@ int main( int argc, const char *argv[] ) {
|
|||
if ( config.opt_use_auth ) {
|
||||
User *user = 0;
|
||||
|
||||
if ( strcmp( config.auth_relay, "none" ) == 0 ) {
|
||||
if ( strcmp(config.auth_relay, "none") == 0 ) {
|
||||
if ( username.length() ) {
|
||||
user = zmLoadUser( username.c_str() );
|
||||
user = zmLoadUser(username.c_str());
|
||||
}
|
||||
} else {
|
||||
//if ( strcmp( config.auth_relay, "hashed" ) == 0 )
|
||||
{
|
||||
if ( *auth ) {
|
||||
user = zmLoadAuthUser( auth, config.auth_hash_ips );
|
||||
user = zmLoadAuthUser(auth, config.auth_hash_ips);
|
||||
}
|
||||
}
|
||||
//else if ( strcmp( config.auth_relay, "plain" ) == 0 )
|
||||
{
|
||||
if ( username.length() && password.length() ) {
|
||||
user = zmLoadUser( username.c_str(), password.c_str() );
|
||||
user = zmLoadUser(username.c_str(), password.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !user ) {
|
||||
Error( "Unable to authenticate user" );
|
||||
Error("Unable to authenticate user");
|
||||
logTerm();
|
||||
zmDbClose();
|
||||
return( -1 );
|
||||
return -1;
|
||||
}
|
||||
ValidateAccess( user, monitor_id );
|
||||
}
|
||||
ValidateAccess(user, monitor_id);
|
||||
} // end if config.opt_use_auth
|
||||
|
||||
hwcaps_detect();
|
||||
zmSetDefaultTermHandler();
|
||||
|
|
|
@ -257,11 +257,14 @@ execpackpack () {
|
|||
fi
|
||||
|
||||
if [ "${TRAVIS}" == "true" ]; then
|
||||
utils/packpack/heartbeat.sh &
|
||||
mypid=$!
|
||||
packpack/packpack $parms > buildlog.txt 2>&1
|
||||
kill $mypid
|
||||
tail -n 3000 buildlog.txt | grep -v ONVIF
|
||||
# Travis will fail the build if the output gets too long
|
||||
# To mitigate that, use grep to filter out some of the noise
|
||||
if [ "${ARCH}" != "armhf" ]; then
|
||||
packpack/packpack $parms | grep -Ev '^(-- Installing:|-- Up-to-date:|Skip blib|Manifying|Installing /build|cp lib|writing output...|copying images...|reading sources...|[Working])'
|
||||
else
|
||||
# Travis never ceases to amaze. For the case of arm emulation, Travis fails the build due to too little output over a 10 minute period. Facepalm.
|
||||
packpack/packpack $parms | grep -Ev '^(-- Installing:|-- Up-to-date:|Skip blib|Installing /build|cp lib|writing output...|copying images...|reading sources...|[Working])'
|
||||
fi
|
||||
else
|
||||
packpack/packpack $parms
|
||||
fi
|
||||
|
|
809
web/ajax/log.php
809
web/ajax/log.php
|
@ -4,443 +4,404 @@
|
|||
# These are the valid columns that you can filter on.
|
||||
$filterFields = array( 'Component', 'ServerId', 'Pid', 'Level', 'File', 'Line' );
|
||||
|
||||
switch ( $_REQUEST['task'] )
|
||||
{
|
||||
case 'create' :
|
||||
{
|
||||
// Silently ignore bogus requests
|
||||
if ( !empty($_POST['level']) && !empty($_POST['message']) )
|
||||
{
|
||||
logInit( array( 'id' => "web_js" ) );
|
||||
switch ( $_REQUEST['task'] ) {
|
||||
case 'create' :
|
||||
{
|
||||
// Silently ignore bogus requests
|
||||
if ( !empty($_POST['level']) && !empty($_POST['message']) ) {
|
||||
logInit(array('id'=>'web_js'));
|
||||
|
||||
$string = $_POST['message'];
|
||||
$string = $_POST['message'];
|
||||
|
||||
$file = !empty($_POST['file']) ? preg_replace( '/\w+:\/\/\w+\//', '', $_POST['file'] ) : '';
|
||||
if ( !empty( $_POST['line'] ) )
|
||||
$line = $_POST['line'];
|
||||
else
|
||||
$line = NULL;
|
||||
$file = !empty($_POST['file']) ? preg_replace( '/\w+:\/\/\w+\//', '', $_POST['file'] ) : '';
|
||||
if ( !empty( $_POST['line'] ) )
|
||||
$line = $_POST['line'];
|
||||
else
|
||||
$line = NULL;
|
||||
|
||||
$levels = array_flip(Logger::$codes);
|
||||
if ( !isset($levels[$_POST['level']]) )
|
||||
Panic( "Unexpected logger level '".$_POST['level']."'" );
|
||||
$level = $levels[$_POST['level']];
|
||||
Logger::fetch()->logPrint( $level, $string, $file, $line );
|
||||
}
|
||||
ajaxResponse();
|
||||
break;
|
||||
$levels = array_flip(Logger::$codes);
|
||||
if ( !isset($levels[$_POST['level']]) )
|
||||
Panic("Unexpected logger level '".$_POST['level']."'");
|
||||
$level = $levels[$_POST['level']];
|
||||
Logger::fetch()->logPrint( $level, $string, $file, $line );
|
||||
}
|
||||
case 'query' :
|
||||
{
|
||||
if ( !canView( 'System' ) )
|
||||
ajaxError( 'Insufficient permissions to view log entries' );
|
||||
ajaxResponse();
|
||||
break;
|
||||
}
|
||||
case 'query' :
|
||||
{
|
||||
if ( !canView('System') )
|
||||
ajaxError('Insufficient permissions to view log entries');
|
||||
|
||||
$servers = Server::find_all();
|
||||
$servers_by_Id = array();
|
||||
# There is probably a better way to do this.
|
||||
foreach ( $servers as $server ) {
|
||||
$servers_by_Id[$server->Id()] = $server;
|
||||
}
|
||||
|
||||
$minTime = isset($_REQUEST['minTime'])?$_REQUEST['minTime']:NULL;
|
||||
$maxTime = isset($_REQUEST['maxTime'])?$_REQUEST['maxTime']:NULL;
|
||||
|
||||
$limit = 100;
|
||||
if ( isset($_REQUEST['limit']) ) {
|
||||
if ( ( !is_integer( $_REQUEST['limit'] ) and !ctype_digit($_REQUEST['limit']) ) ) {
|
||||
Error("Invalid value for limit " . $_REQUEST['limit'] );
|
||||
} else {
|
||||
$limit = $_REQUEST['limit'];
|
||||
}
|
||||
}
|
||||
$sortField = 'TimeKey';
|
||||
if ( isset($_REQUEST['sortField']) ) {
|
||||
if ( ! in_array( $_REQUEST['sortField'], $filterFields ) and ( $_REQUEST['sortField'] != 'TimeKey' ) ) {
|
||||
Error("Invalid sort field " . $_REQUEST['sortField'] );
|
||||
} else {
|
||||
$sortField = $_REQUEST['sortField'];
|
||||
}
|
||||
}
|
||||
$sortOrder = (isset($_REQUEST['sortOrder']) and $_REQUEST['sortOrder']) == 'asc' ? 'asc':'desc';
|
||||
$filter = isset($_REQUEST['filter'])?$_REQUEST['filter']:array();
|
||||
|
||||
$total = dbFetchOne( 'SELECT count(*) AS Total FROM Logs', 'Total' );
|
||||
$sql = 'SELECT * FROM Logs';
|
||||
$where = array();
|
||||
$values = array();
|
||||
if ( $minTime ) {
|
||||
$where[] = "TimeKey > ?";
|
||||
$values[] = $minTime;
|
||||
} elseif ( $maxTime ) {
|
||||
$where[] = "TimeKey < ?";
|
||||
$values[] = $maxTime;
|
||||
}
|
||||
|
||||
foreach ( $filter as $field=>$value ) {
|
||||
if ( ! in_array( $field, $filterFields ) ) {
|
||||
Error("$field is not in valid filter fields");
|
||||
continue;
|
||||
}
|
||||
if ( $field == 'Level' ){
|
||||
$where[] = $field." <= ?";
|
||||
$values[] = $value;
|
||||
} else {
|
||||
$where[] = $field." = ?";
|
||||
$values[] = $value;
|
||||
}
|
||||
}
|
||||
if ( count($where) )
|
||||
$sql.= ' WHERE '.join( ' AND ', $where );
|
||||
$sql .= " order by ".$sortField." ".$sortOrder." limit ".$limit;
|
||||
$logs = array();
|
||||
foreach ( dbFetchAll( $sql, NULL, $values ) as $log ) {
|
||||
$log['DateTime'] = preg_replace( '/^\d+/', strftime( '%Y-%m-%d %H:%M:%S', intval($log['TimeKey']) ), $log['TimeKey'] );
|
||||
$log['Server'] = ( $log['ServerId'] and isset($servers_by_Id[$log['ServerId']]) ) ? $servers_by_Id[$log['ServerId']]->Name() : '';
|
||||
$log['Message'] = preg_replace('/[\x00-\x1F\x7F-\xFF]/', '', $log['Message'] );
|
||||
$logs[] = $log;
|
||||
}
|
||||
$options = array();
|
||||
$where = array();
|
||||
$values = array();
|
||||
foreach( $filter as $field=>$value ) {
|
||||
if ( $field == 'Level' ) {
|
||||
$where[$field] = $field." <= ?";
|
||||
$values[$field] = $value;
|
||||
} else {
|
||||
$where[$field] = $field." = ?";
|
||||
$values[$field] = $value;
|
||||
}
|
||||
}
|
||||
foreach( $filterFields as $field )
|
||||
{
|
||||
$sql = "SELECT DISTINCT $field FROM Logs WHERE NOT isnull($field)";
|
||||
$fieldWhere = array_diff_key( $where, array( $field=>true ) );
|
||||
$fieldValues = array_diff_key( $values, array( $field=>true ) );
|
||||
if ( count($fieldWhere) )
|
||||
$sql.= " AND ".join( ' AND ', $fieldWhere );
|
||||
$sql.= " ORDER BY $field ASC";
|
||||
if ( $field == 'Level' )
|
||||
{
|
||||
foreach( dbFetchAll( $sql, $field, array_values($fieldValues) ) as $value )
|
||||
if ( $value <= Logger::INFO )
|
||||
$options[$field][$value] = Logger::$codes[$value];
|
||||
else
|
||||
$options[$field][$value] = "DB".$value;
|
||||
}
|
||||
elseif ( $field == 'ServerId' )
|
||||
{
|
||||
foreach( dbFetchAll( $sql, $field, array_values($fieldValues) ) as $value )
|
||||
$options['ServerId'][$value] = ( $value and isset($servers_by_Id[$value]) ) ? $servers_by_Id[$value]->Name() : '';
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach( dbFetchAll( $sql, $field, array_values( $fieldValues ) ) as $value )
|
||||
if ( $value != '' )
|
||||
$options[$field][] = $value;
|
||||
}
|
||||
}
|
||||
if ( count($filter) )
|
||||
{
|
||||
$sql = "SELECT count(*) AS Available FROM Logs WHERE ".join( ' AND ', $where );
|
||||
$available = dbFetchOne( $sql, 'Available', array_values($values) );
|
||||
}
|
||||
ajaxResponse( array(
|
||||
'updated' => preg_match( '/%/', DATE_FMT_CONSOLE_LONG )?strftime( DATE_FMT_CONSOLE_LONG ):date( DATE_FMT_CONSOLE_LONG ),
|
||||
'total' => $total,
|
||||
'available' => isset($available)?$available:$total,
|
||||
'logs' => $logs,
|
||||
'state' => logState(),
|
||||
'options' => $options
|
||||
) );
|
||||
break;
|
||||
$servers = Server::find_all();
|
||||
$servers_by_Id = array();
|
||||
# There is probably a better way to do this.
|
||||
foreach ( $servers as $server ) {
|
||||
$servers_by_Id[$server->Id()] = $server;
|
||||
}
|
||||
case 'export' :
|
||||
|
||||
$minTime = isset($_REQUEST['minTime'])?$_REQUEST['minTime']:NULL;
|
||||
$maxTime = isset($_REQUEST['maxTime'])?$_REQUEST['maxTime']:NULL;
|
||||
|
||||
$limit = 100;
|
||||
if ( isset($_REQUEST['limit']) ) {
|
||||
if ( ( !is_integer( $_REQUEST['limit'] ) and !ctype_digit($_REQUEST['limit']) ) ) {
|
||||
Error('Invalid value for limit ' . $_REQUEST['limit'] );
|
||||
} else {
|
||||
$limit = $_REQUEST['limit'];
|
||||
}
|
||||
}
|
||||
$sortField = 'TimeKey';
|
||||
if ( isset($_REQUEST['sortField']) ) {
|
||||
if ( ! in_array( $_REQUEST['sortField'], $filterFields ) and ( $_REQUEST['sortField'] != 'TimeKey' ) ) {
|
||||
Error("Invalid sort field " . $_REQUEST['sortField'] );
|
||||
} else {
|
||||
$sortField = $_REQUEST['sortField'];
|
||||
}
|
||||
}
|
||||
$sortOrder = (isset($_REQUEST['sortOrder']) and $_REQUEST['sortOrder']) == 'asc' ? 'asc':'desc';
|
||||
$filter = isset($_REQUEST['filter'])?$_REQUEST['filter']:array();
|
||||
|
||||
$total = dbFetchOne('SELECT count(*) AS Total FROM Logs', 'Total');
|
||||
$sql = 'SELECT * FROM Logs';
|
||||
$where = array();
|
||||
$values = array();
|
||||
if ( $minTime ) {
|
||||
$where[] = 'TimeKey > ?';
|
||||
$values[] = $minTime;
|
||||
} elseif ( $maxTime ) {
|
||||
$where[] = 'TimeKey < ?';
|
||||
$values[] = $maxTime;
|
||||
}
|
||||
|
||||
foreach ( $filter as $field=>$value ) {
|
||||
if ( ! in_array($field, $filterFields) ) {
|
||||
Error("$field is not in valid filter fields");
|
||||
continue;
|
||||
}
|
||||
if ( $field == 'Level' ){
|
||||
$where[] = $field.' <= ?';
|
||||
$values[] = $value;
|
||||
} else {
|
||||
$where[] = $field.' = ?';
|
||||
$values[] = $value;
|
||||
}
|
||||
}
|
||||
$options = array();
|
||||
if ( count($where) )
|
||||
$sql.= ' WHERE '.join( ' AND ', $where );
|
||||
$sql .= ' ORDER BY '.$sortField.' '.$sortOrder.' LIMIT '.$limit;
|
||||
$logs = array();
|
||||
foreach ( dbFetchAll($sql, NULL, $values) as $log ) {
|
||||
$log['DateTime'] = preg_replace('/^\d+/', strftime('%Y-%m-%d %H:%M:%S', intval($log['TimeKey'])), $log['TimeKey']);
|
||||
$log['Server'] = ( $log['ServerId'] and isset($servers_by_Id[$log['ServerId']]) ) ? $servers_by_Id[$log['ServerId']]->Name() : '';
|
||||
$log['Message'] = preg_replace('/[\x00-\x1F\x7F-\xFF]/', '', $log['Message'] );
|
||||
foreach( $filterFields as $field ) {
|
||||
if ( ! isset( $options[$field] ) )
|
||||
$options[$field] = array();
|
||||
$value = $log[$field];
|
||||
|
||||
if ( $field == 'Level' ) {
|
||||
if ( $value <= Logger::INFO )
|
||||
$options[$field][$value] = Logger::$codes[$value];
|
||||
else
|
||||
$options[$field][$value] = 'DB'.$value;
|
||||
} else if ( $field == 'ServerId' ) {
|
||||
$options['ServerId'][$value] = ( $value and isset($servers_by_Id[$value]) ) ? $servers_by_Id[$value]->Name() : '';
|
||||
} else if ( isset($log[$field]) ) {
|
||||
$options[$field][$log[$field]] = $log[$field];
|
||||
}
|
||||
}
|
||||
$logs[] = $log;
|
||||
}
|
||||
|
||||
$available = count($logs);
|
||||
ajaxResponse( array(
|
||||
'updated' => preg_match('/%/', DATE_FMT_CONSOLE_LONG)?strftime(DATE_FMT_CONSOLE_LONG):date(DATE_FMT_CONSOLE_LONG),
|
||||
'total' => $total,
|
||||
'available' => isset($available)?$available:$total,
|
||||
'logs' => $logs,
|
||||
'state' => logState(),
|
||||
'options' => $options
|
||||
) );
|
||||
break;
|
||||
}
|
||||
case 'export' :
|
||||
{
|
||||
if ( !canView('System') )
|
||||
ajaxError('Insufficient permissions to export logs');
|
||||
|
||||
$minTime = isset($_POST['minTime'])?$_POST['minTime']:NULL;
|
||||
$maxTime = isset($_POST['maxTime'])?$_POST['maxTime']:NULL;
|
||||
if ( !is_null($minTime) && !is_null($maxTime) && $minTime > $maxTime ) {
|
||||
$tempTime = $minTime;
|
||||
$minTime = $maxTime;
|
||||
$maxTime = $tempTime;
|
||||
}
|
||||
//$limit = isset($_POST['limit'])?$_POST['limit']:1000;
|
||||
$filter = isset($_POST['filter'])?$_POST['filter']:array();
|
||||
$sortField = 'TimeKey';
|
||||
if ( isset($_POST['sortField']) ) {
|
||||
if ( ! in_array( $_POST['sortField'], $filterFields ) and ( $_POST['sortField'] != 'TimeKey' ) ) {
|
||||
Error("Invalid sort field " . $_POST['sortField'] );
|
||||
} else {
|
||||
$sortField = $_POST['sortField'];
|
||||
}
|
||||
}
|
||||
$sortOrder = (isset($_POST['sortOrder']) and $_POST['sortOrder']) == 'asc' ? 'asc':'desc';
|
||||
|
||||
$servers = Server::find_all();
|
||||
$servers_by_Id = array();
|
||||
# There is probably a better way to do this.
|
||||
foreach ( $servers as $server ) {
|
||||
$servers_by_Id[$server->Id()] = $server;
|
||||
}
|
||||
|
||||
$sql = 'SELECT * FROM Logs';
|
||||
$where = array();
|
||||
$values = array();
|
||||
if ( $minTime ) {
|
||||
preg_match('/(.+)(\.\d+)/', $minTime, $matches);
|
||||
$minTime = strtotime($matches[1]).$matches[2];
|
||||
$where[] = 'TimeKey >= ?';
|
||||
$values[] = $minTime;
|
||||
}
|
||||
if ( $maxTime ) {
|
||||
preg_match('/(.+)(\.\d+)/', $maxTime, $matches);
|
||||
$maxTime = strtotime($matches[1]).$matches[2];
|
||||
$where[] = 'TimeKey <= ?';
|
||||
$values[] = $maxTime;
|
||||
}
|
||||
foreach ( $filter as $field=>$value ) {
|
||||
if ( $value != '' ) {
|
||||
if ( $field == 'Level' ) {
|
||||
$where[] = $field.' <= ?';
|
||||
$values[] = $value;
|
||||
} else {
|
||||
$where[] = $field.' = ?';
|
||||
$values[] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( count($where) )
|
||||
$sql.= ' WHERE '.join( ' AND ', $where );
|
||||
$sql .= ' ORDER BY '.$sortField.' '.$sortOrder;
|
||||
//$sql .= " limit ".dbEscape($limit);
|
||||
$format = isset($_POST['format'])?$_POST['format']:'text';
|
||||
switch( $format ) {
|
||||
case 'text' :
|
||||
$exportExt = 'txt';
|
||||
break;
|
||||
case 'tsv' :
|
||||
$exportExt = 'tsv';
|
||||
break;
|
||||
case 'html' :
|
||||
$exportExt = 'html';
|
||||
break;
|
||||
case 'xml' :
|
||||
$exportExt = 'xml';
|
||||
break;
|
||||
default :
|
||||
Fatal("Unrecognised log export format '$format'");
|
||||
}
|
||||
$exportKey = substr(md5(rand()),0,8);
|
||||
$exportFile = "zm-log.$exportExt";
|
||||
$exportPath = ZM_PATH_SWAP."/zm-log-$exportKey.$exportExt";
|
||||
if ( !($exportFP = fopen( $exportPath, "w" )) )
|
||||
Fatal("Unable to open log export file $exportPath");
|
||||
$logs = array();
|
||||
foreach ( dbFetchAll( $sql, NULL, $values ) as $log ) {
|
||||
$log['DateTime'] = preg_replace( '/^\d+/', strftime( "%Y-%m-%d %H:%M:%S", intval($log['TimeKey']) ), $log['TimeKey'] );
|
||||
$log['Server'] = ( $log['ServerId'] and isset($servers_by_Id[$log['ServerId']]) ) ? $servers_by_Id[$log['ServerId']]->Name() : '';
|
||||
$logs[] = $log;
|
||||
}
|
||||
switch( $format ) {
|
||||
case 'text' :
|
||||
{
|
||||
if ( !canView( 'System' ) )
|
||||
ajaxError( 'Insufficient permissions to export logs' );
|
||||
|
||||
$minTime = isset($_POST['minTime'])?$_POST['minTime']:NULL;
|
||||
$maxTime = isset($_POST['maxTime'])?$_POST['maxTime']:NULL;
|
||||
if ( !is_null($minTime) && !is_null($maxTime) && $minTime > $maxTime )
|
||||
{
|
||||
$tempTime = $minTime;
|
||||
$minTime = $maxTime;
|
||||
$maxTime = $tempTime;
|
||||
}
|
||||
//$limit = isset($_POST['limit'])?$_POST['limit']:1000;
|
||||
$filter = isset($_POST['filter'])?$_POST['filter']:array();
|
||||
$sortField = 'TimeKey';
|
||||
if ( isset($_POST['sortField']) ) {
|
||||
if ( ! in_array( $_POST['sortField'], $filterFields ) and ( $_POST['sortField'] != 'TimeKey' ) ) {
|
||||
Error("Invalid sort field " . $_POST['sortField'] );
|
||||
} else {
|
||||
$sortField = $_POST['sortField'];
|
||||
}
|
||||
}
|
||||
$sortOrder = (isset($_POST['sortOrder']) and $_POST['sortOrder']) == 'asc' ? 'asc':'desc';
|
||||
|
||||
$servers = Server::find_all();
|
||||
$servers_by_Id = array();
|
||||
# There is probably a better way to do this.
|
||||
foreach ( $servers as $server ) {
|
||||
$servers_by_Id[$server->Id()] = $server;
|
||||
}
|
||||
|
||||
$sql = "select * from Logs";
|
||||
$where = array();
|
||||
$values = array();
|
||||
if ( $minTime )
|
||||
{
|
||||
preg_match( '/(.+)(\.\d+)/', $minTime, $matches );
|
||||
$minTime = strtotime($matches[1]).$matches[2];
|
||||
$where[] = "TimeKey >= ?";
|
||||
$values[] = $minTime;
|
||||
}
|
||||
if ( $maxTime )
|
||||
{
|
||||
preg_match( '/(.+)(\.\d+)/', $maxTime, $matches );
|
||||
$maxTime = strtotime($matches[1]).$matches[2];
|
||||
$where[] = "TimeKey <= ?";
|
||||
$values[] = $maxTime;
|
||||
}
|
||||
foreach ( $filter as $field=>$value ) {
|
||||
if ( $value != '' ) {
|
||||
if ( $field == 'Level' ) {
|
||||
$where[] = $field." <= ?";
|
||||
$values[] = $value;
|
||||
} else {
|
||||
$where[] = $field." = ?'";
|
||||
$values[] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( count($where) )
|
||||
$sql.= " where ".join( " and ", $where );
|
||||
$sql .= " order by ".$sortField." ".$sortOrder;
|
||||
//$sql .= " limit ".dbEscape($limit);
|
||||
$format = isset($_POST['format'])?$_POST['format']:'text';
|
||||
switch( $format )
|
||||
{
|
||||
case 'text' :
|
||||
$exportExt = "txt";
|
||||
break;
|
||||
case 'tsv' :
|
||||
$exportExt = "tsv";
|
||||
break;
|
||||
case 'html' :
|
||||
$exportExt = "html";
|
||||
break;
|
||||
case 'xml' :
|
||||
$exportExt = "xml";
|
||||
break;
|
||||
default :
|
||||
Fatal( "Unrecognised log export format '$format'" );
|
||||
}
|
||||
$exportKey = substr(md5(rand()),0,8);
|
||||
$exportFile = "zm-log.$exportExt";
|
||||
$exportPath = ZM_PATH_SWAP."/zm-log-$exportKey.$exportExt";
|
||||
if ( !($exportFP = fopen( $exportPath, "w" )) )
|
||||
Fatal( "Unable to open log export file $exportPath" );
|
||||
$logs = array();
|
||||
foreach ( dbFetchAll( $sql, NULL, $values ) as $log )
|
||||
{
|
||||
$log['DateTime'] = preg_replace( '/^\d+/', strftime( "%Y-%m-%d %H:%M:%S", intval($log['TimeKey']) ), $log['TimeKey'] );
|
||||
$log['Server'] = ( $log['ServerId'] and isset($servers_by_Id[$log['ServerId']]) ) ? $servers_by_Id[$log['ServerId']]->Name() : '';
|
||||
$logs[] = $log;
|
||||
}
|
||||
switch( $format )
|
||||
{
|
||||
case 'text' :
|
||||
{
|
||||
foreach ( $logs as $log )
|
||||
{
|
||||
if ( $log['Line'] )
|
||||
fprintf( $exportFP, "%s %s[%d].%s-%s/%d [%s]\n", $log['DateTime'], $log['Component'], $log['Pid'], $log['Code'], $log['File'], $log['Line'], $log['Message'] );
|
||||
else
|
||||
fprintf( $exportFP, "%s %s[%d].%s-%s [%s]\n", $log['DateTime'], $log['Component'], $log['Pid'], $log['Code'], $log['File'], $log['Message'] );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'tsv' :
|
||||
{
|
||||
# This line doesn't need fprintf, it could use fwrite
|
||||
fprintf( $exportFP, join( "\t",
|
||||
translate('DateTime'),
|
||||
translate('Component'),
|
||||
translate('Server'),
|
||||
translate('Pid'),
|
||||
translate('Level'),
|
||||
translate('Message'),
|
||||
translate('File'),
|
||||
translate('Line')
|
||||
)."\n" );
|
||||
foreach ( $logs as $log )
|
||||
{
|
||||
fprintf( $exportFP, "%s\t%s\t%s\t%d\t%s\t%s\t%s\t%s\n", $log['DateTime'], $log['Component'], $log['Server'], $log['Pid'], $log['Code'], $log['Message'], $log['File'], $log['Line'] );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'html' :
|
||||
{
|
||||
fwrite( $exportFP,
|
||||
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>'.translate('ZoneMinderLog').'</title>
|
||||
<style type="text/css">
|
||||
body, h3, p, table, td {
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
font-size: 11px;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
th {
|
||||
font-weight: bold;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid #888888;
|
||||
padding: 1px 2px;
|
||||
}
|
||||
tr.log-fat td {
|
||||
background-color:#ffcccc;
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
tr.log-err td {
|
||||
background-color:#ffcccc;
|
||||
}
|
||||
tr.log-war td {
|
||||
background-color: #ffe4b5;
|
||||
}
|
||||
tr.log-dbg td {
|
||||
color: #666666;
|
||||
font-style: italic;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
foreach ( $logs as $log ) {
|
||||
if ( $log['Line'] )
|
||||
fprintf( $exportFP, "%s %s[%d].%s-%s/%d [%s]\n",
|
||||
$log['DateTime'], $log['Component'], $log['Pid'], $log['Code'], $log['File'], $log['Line'], $log['Message'] );
|
||||
else
|
||||
fprintf( $exportFP, "%s %s[%d].%s-%s [%s]\n",
|
||||
$log['DateTime'], $log['Component'], $log['Pid'], $log['Code'], $log['File'], $log['Message'] );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'tsv' :
|
||||
{
|
||||
# This line doesn't need fprintf, it could use fwrite
|
||||
fprintf( $exportFP, join( "\t",
|
||||
translate('DateTime'),
|
||||
translate('Component'),
|
||||
translate('Server'),
|
||||
translate('Pid'),
|
||||
translate('Level'),
|
||||
translate('Message'),
|
||||
translate('File'),
|
||||
translate('Line')
|
||||
)."\n" );
|
||||
foreach ( $logs as $log ) {
|
||||
fprintf( $exportFP, "%s\t%s\t%s\t%d\t%s\t%s\t%s\t%s\n", $log['DateTime'], $log['Component'], $log['Server'], $log['Pid'], $log['Code'], $log['Message'], $log['File'], $log['Line'] );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'html' :
|
||||
{
|
||||
fwrite( $exportFP,
|
||||
'
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>'.translate('ZoneMinderLog').'</title>
|
||||
<style type="text/css">
|
||||
body, h3, p, table, td {
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
font-size: 11px;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
th {
|
||||
font-weight: bold;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid #888888;
|
||||
padding: 1px 2px;
|
||||
}
|
||||
tr.log-fat td {
|
||||
background-color:#ffcccc;
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
tr.log-err td {
|
||||
background-color:#ffcccc;
|
||||
}
|
||||
tr.log-war td {
|
||||
background-color: #ffe4b5;
|
||||
}
|
||||
tr.log-dbg td {
|
||||
color: #666666;
|
||||
font-style: italic;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h3>'.translate('ZoneMinderLog').'</h3>
|
||||
<p>'.htmlspecialchars(preg_match( '/%/', DATE_FMT_CONSOLE_LONG )?strftime( DATE_FMT_CONSOLE_LONG ):date( DATE_FMT_CONSOLE_LONG )).'</p>
|
||||
<p>'.count($logs).' '.translate('Logs').'</p>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr><th>'.translate('DateTime').'</th><th>'.translate('Component').'</th><th>'.translate('Server').'</th><th>'.translate('Pid').'</th><th>'.translate('Level').'</th><th>'.translate('Message').'</th><th>'.translate('File').'</th><th>'.translate('Line').'</th></tr>
|
||||
' );
|
||||
foreach ( $logs as $log )
|
||||
{
|
||||
$classLevel = $log['Level'];
|
||||
if ( $classLevel < Logger::FATAL )
|
||||
$classLevel = Logger::FATAL;
|
||||
elseif ( $classLevel > Logger::DEBUG )
|
||||
$classLevel = Logger::DEBUG;
|
||||
$logClass = 'log-'.strtolower(Logger::$codes[$classLevel]);
|
||||
fprintf( $exportFP, " <tr class=\"%s\"><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n", $logClass, $log['DateTime'], $log['Component'], $log['Server'], $log['Pid'], $log['Code'], $log['Message'], $log['File'], $log['Line'] );
|
||||
}
|
||||
fwrite( $exportFP,
|
||||
' </tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>' );
|
||||
break;
|
||||
}
|
||||
case 'xml' :
|
||||
{
|
||||
fwrite( $exportFP,
|
||||
'<?xml version="1.0" encoding="utf-8"?>
|
||||
<logexport title="'.translate('ZoneMinderLog').'" date="'.htmlspecialchars(preg_match( '/%/', DATE_FMT_CONSOLE_LONG )?strftime( DATE_FMT_CONSOLE_LONG ):date( DATE_FMT_CONSOLE_LONG )).'">
|
||||
<selector>'.$_POST['selector'].'</selector>' );
|
||||
foreach ( $filter as $field=>$value )
|
||||
if ( $value != '' )
|
||||
fwrite( $exportFP,
|
||||
' <filter>
|
||||
<'.strtolower($field).'>'.htmlspecialchars($value).'</'.strtolower($field).'>
|
||||
</filter>' );
|
||||
fwrite( $exportFP,
|
||||
' <columns>
|
||||
<column field="datetime">'.translate('DateTime').'</column><column field="component">'.translate('Component').'</column><column field="'.translate('Server').'</column><column field="pid">'.translate('Pid').'</column><column field="level">'.translate('Level').'</column><column field="message">'.translate('Message').'</column><column field="file">'.translate('File').'</column><column field="line">'.translate('Line').'</column>
|
||||
</columns>
|
||||
<logs count="'.count($logs).'">
|
||||
' );
|
||||
foreach ( $logs as $log )
|
||||
{
|
||||
fprintf( $exportFP,
|
||||
" <log>
|
||||
<datetime>%s</datetime>
|
||||
<component>%s</component>
|
||||
<server>%s</server>
|
||||
<pid>%d</pid>
|
||||
<level>%s</level>
|
||||
<message><![CDATA[%s]]></message>
|
||||
<file>%s</file>
|
||||
<line>%d</line>
|
||||
</log>\n", $log['DateTime'], $log['Component'], $log['Server'], $log['Pid'], $log['Code'], utf8_decode( $log['Message'] ), $log['File'], $log['Line'] );
|
||||
}
|
||||
fwrite( $exportFP,
|
||||
' </logs>
|
||||
</logexport>' );
|
||||
break;
|
||||
}
|
||||
$exportExt = "xml";
|
||||
break;
|
||||
}
|
||||
fclose( $exportFP );
|
||||
ajaxResponse( array(
|
||||
'key' => $exportKey,
|
||||
'format' => $format,
|
||||
) );
|
||||
break;
|
||||
<tbody>
|
||||
<tr><th>'.translate('DateTime').'</th><th>'.translate('Component').'</th><th>'.translate('Server').'</th><th>'.translate('Pid').'</th><th>'.translate('Level').'</th><th>'.translate('Message').'</th><th>'.translate('File').'</th><th>'.translate('Line').'</th></tr>
|
||||
' );
|
||||
foreach ( $logs as $log ) {
|
||||
$classLevel = $log['Level'];
|
||||
if ( $classLevel < Logger::FATAL )
|
||||
$classLevel = Logger::FATAL;
|
||||
elseif ( $classLevel > Logger::DEBUG )
|
||||
$classLevel = Logger::DEBUG;
|
||||
$logClass = 'log-'.strtolower(Logger::$codes[$classLevel]);
|
||||
fprintf( $exportFP, " <tr class=\"%s\"><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n", $logClass, $log['DateTime'], $log['Component'], $log['Server'], $log['Pid'], $log['Code'], $log['Message'], $log['File'], $log['Line'] );
|
||||
}
|
||||
case 'download' :
|
||||
fwrite( $exportFP,
|
||||
' </tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>' );
|
||||
break;
|
||||
}
|
||||
case 'xml' :
|
||||
{
|
||||
if ( !canView( 'System' ) )
|
||||
ajaxError( 'Insufficient permissions to download logs' );
|
||||
|
||||
if ( empty($_REQUEST['key']) )
|
||||
Fatal( "No log export key given" );
|
||||
$exportKey = $_REQUEST['key'];
|
||||
if ( empty($_REQUEST['format']) )
|
||||
Fatal( "No log export format given" );
|
||||
$format = $_REQUEST['format'];
|
||||
|
||||
switch( $format )
|
||||
{
|
||||
case 'text' :
|
||||
$exportExt = "txt";
|
||||
break;
|
||||
case 'tsv' :
|
||||
$exportExt = "tsv";
|
||||
break;
|
||||
case 'html' :
|
||||
$exportExt = "html";
|
||||
break;
|
||||
case 'xml' :
|
||||
$exportExt = "xml";
|
||||
break;
|
||||
default :
|
||||
Fatal( "Unrecognised log export format '$format'" );
|
||||
}
|
||||
|
||||
$exportFile = "zm-log.$exportExt";
|
||||
$exportPath = ZM_PATH_SWAP."/zm-log-$exportKey.$exportExt";
|
||||
|
||||
header( "Pragma: public" );
|
||||
header( "Expires: 0" );
|
||||
header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
|
||||
header( "Cache-Control: private", false ); // required by certain browsers
|
||||
header( "Content-Description: File Transfer" );
|
||||
header( 'Content-Disposition: attachment; filename="'.$exportFile.'"' );
|
||||
header( "Content-Transfer-Encoding: binary" );
|
||||
header( "Content-Type: application/force-download" );
|
||||
header( "Content-Length: ".filesize($exportPath) );
|
||||
readfile( $exportPath );
|
||||
exit( 0 );
|
||||
break;
|
||||
fwrite( $exportFP,
|
||||
'<?xml version="1.0" encoding="utf-8"?>
|
||||
<logexport title="'.translate('ZoneMinderLog').'" date="'.htmlspecialchars(preg_match( '/%/', DATE_FMT_CONSOLE_LONG )?strftime( DATE_FMT_CONSOLE_LONG ):date( DATE_FMT_CONSOLE_LONG )).'">
|
||||
<selector>'.$_POST['selector'].'</selector>' );
|
||||
foreach ( $filter as $field=>$value )
|
||||
if ( $value != '' )
|
||||
fwrite( $exportFP,
|
||||
' <filter>
|
||||
<'.strtolower($field).'>'.htmlspecialchars($value).'</'.strtolower($field).'>
|
||||
</filter>' );
|
||||
fwrite( $exportFP,
|
||||
' <columns>
|
||||
<column field="datetime">'.translate('DateTime').'</column><column field="component">'.translate('Component').'</column><column field="'.translate('Server').'</column><column field="pid">'.translate('Pid').'</column><column field="level">'.translate('Level').'</column><column field="message">'.translate('Message').'</column><column field="file">'.translate('File').'</column><column field="line">'.translate('Line').'</column>
|
||||
</columns>
|
||||
<logs count="'.count($logs).'">
|
||||
' );
|
||||
foreach ( $logs as $log ) {
|
||||
fprintf( $exportFP,
|
||||
" <log>
|
||||
<datetime>%s</datetime>
|
||||
<component>%s</component>
|
||||
<server>%s</server>
|
||||
<pid>%d</pid>
|
||||
<level>%s</level>
|
||||
<message><![CDATA[%s]]></message>
|
||||
<file>%s</file>
|
||||
<line>%d</line>
|
||||
</log>\n", $log['DateTime'], $log['Component'], $log['Server'], $log['Pid'], $log['Code'], utf8_decode( $log['Message'] ), $log['File'], $log['Line'] );
|
||||
}
|
||||
fwrite( $exportFP,
|
||||
' </logs>
|
||||
</logexport>' );
|
||||
break;
|
||||
}
|
||||
$exportExt = "xml";
|
||||
break;
|
||||
}
|
||||
fclose( $exportFP );
|
||||
ajaxResponse( array(
|
||||
'key' => $exportKey,
|
||||
'format' => $format,
|
||||
) );
|
||||
break;
|
||||
}
|
||||
case 'download' :
|
||||
{
|
||||
if ( !canView('System') )
|
||||
ajaxError('Insufficient permissions to download logs');
|
||||
|
||||
if ( empty($_REQUEST['key']) )
|
||||
Fatal( "No log export key given" );
|
||||
$exportKey = $_REQUEST['key'];
|
||||
if ( empty($_REQUEST['format']) )
|
||||
Fatal( "No log export format given" );
|
||||
$format = $_REQUEST['format'];
|
||||
|
||||
switch( $format ) {
|
||||
case 'text' :
|
||||
$exportExt = 'txt';
|
||||
break;
|
||||
case 'tsv' :
|
||||
$exportExt = 'tsv';
|
||||
break;
|
||||
case 'html' :
|
||||
$exportExt = 'html';
|
||||
break;
|
||||
case 'xml' :
|
||||
$exportExt = 'xml';
|
||||
break;
|
||||
default :
|
||||
Fatal("Unrecognised log export format '$format'");
|
||||
}
|
||||
|
||||
$exportFile = "zm-log.$exportExt";
|
||||
$exportPath = ZM_PATH_SWAP."/zm-log-$exportKey.$exportExt";
|
||||
|
||||
header( "Pragma: public" );
|
||||
header( "Expires: 0" );
|
||||
header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
|
||||
header( "Cache-Control: private", false ); // required by certain browsers
|
||||
header( "Content-Description: File Transfer" );
|
||||
header( 'Content-Disposition: attachment; filename="'.$exportFile.'"' );
|
||||
header( "Content-Transfer-Encoding: binary" );
|
||||
header( "Content-Type: application/force-download" );
|
||||
header( "Content-Length: ".filesize($exportPath) );
|
||||
readfile( $exportPath );
|
||||
exit( 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ajaxError( 'Unrecognised action or insufficient permissions' );
|
||||
|
||||
ajaxError('Unrecognised action or insufficient permissions');
|
||||
?>
|
||||
|
|
|
@ -22,13 +22,9 @@ if ( sem_acquire($semaphore,1) !== false ) {
|
|||
if ( file_exists( $localSocketFile ) ) {
|
||||
Warning("sock file $localSocketFile already exists?! Is someone else talking to zms?");
|
||||
// They could be. We can maybe have concurrent requests from a browser.
|
||||
} else {
|
||||
Logger::Debug("socket file does not exist, we should be good to connect.");
|
||||
}
|
||||
if ( ! socket_bind( $socket, $localSocketFile ) ) {
|
||||
ajaxError( "socket_bind( $localSocketFile ) failed: ".socket_strerror(socket_last_error()) );
|
||||
} else {
|
||||
Logger::Debug("Bound to $localSocketFile");
|
||||
ajaxError("socket_bind( $localSocketFile ) failed: ".socket_strerror(socket_last_error()) );
|
||||
}
|
||||
|
||||
switch ( $_REQUEST['command'] ) {
|
||||
|
@ -81,7 +77,6 @@ if ( sem_acquire($semaphore,1) !== false ) {
|
|||
$eSockets = NULL;
|
||||
|
||||
$timeout = MSG_TIMEOUT - ( time() - $start_time );
|
||||
Logger::Debug("TImeout is: $timeout/1000 seconds. " );
|
||||
|
||||
$numSockets = socket_select( $rSockets, $wSockets, $eSockets, intval($timeout/1000), ($timeout%1000)*1000 );
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@ class EventsController extends AppController {
|
|||
$event['Event']['Prev'] = $event_neighbors['prev']['Event']['Id'];
|
||||
|
||||
$event['Event']['fileExists'] = $this->Event->fileExists($event['Event']);
|
||||
$event['Event']['fileSize'] = $this->Event->fileSize($event['Event']);
|
||||
|
||||
# Also get the previous and next events for the same monitor
|
||||
$event_monitor_neighbors = $this->Event->find('neighbors', array(
|
||||
|
|
|
@ -332,25 +332,18 @@ class MonitorsController extends AppController {
|
|||
}
|
||||
|
||||
public function daemonControl($id, $command, $monitor=null, $daemon=null) {
|
||||
$args = '';
|
||||
$daemons = array();
|
||||
|
||||
if (!$monitor) {
|
||||
if ( !$monitor ) {
|
||||
// Need to see if it is local or remote
|
||||
$monitor = $this->Monitor->find('first', array(
|
||||
'fields' => array('Type', 'Function'),
|
||||
'fields' => array('Type', 'Function', 'Device'),
|
||||
'conditions' => array('Id' => $id)
|
||||
));
|
||||
$monitor = $monitor['Monitor'];
|
||||
}
|
||||
|
||||
if ($monitor['Type'] == 'Local') {
|
||||
$args = '-d ' . $monitor['Device'];
|
||||
} else {
|
||||
$args = '-m ' . $id;
|
||||
}
|
||||
|
||||
if ($monitor['Function'] == 'Monitor') {
|
||||
if ( $monitor['Function'] == 'Monitor' ) {
|
||||
array_push($daemons, 'zmc');
|
||||
} else {
|
||||
array_push($daemons, 'zmc', 'zma');
|
||||
|
@ -359,6 +352,13 @@ class MonitorsController extends AppController {
|
|||
$zm_path_bin = Configure::read('ZM_PATH_BIN');
|
||||
|
||||
foreach ($daemons as $daemon) {
|
||||
$args = '';
|
||||
if ( $daemon == 'zmc' and $monitor['Type'] == 'Local') {
|
||||
$args = '-d ' . $monitor['Device'];
|
||||
} else {
|
||||
$args = '-m ' . $id;
|
||||
}
|
||||
|
||||
$shellcmd = escapeshellcmd("$zm_path_bin/zmdc.pl $command $daemon $args");
|
||||
$status = exec( $shellcmd );
|
||||
}
|
||||
|
|
|
@ -115,13 +115,13 @@ class Event extends AppModel {
|
|||
} // end function Relative_Path()
|
||||
|
||||
|
||||
public function fileExists( $event ) {
|
||||
public function fileExists($event) {
|
||||
//$data = $this->findById($id);
|
||||
//return $data['Event']['dataset_filename'];
|
||||
$storage = $this->Storage->findById( $event['StorageId'] );
|
||||
$storage = $this->Storage->findById($event['StorageId']);
|
||||
|
||||
if ( $event['DefaultVideo'] ) {
|
||||
if ( file_exists( $storage['Storage']['Path'].'/'.$this->Relative_Path($event).'/'.$event['DefaultVideo'] ) ) {
|
||||
if ( file_exists($storage['Storage']['Path'].'/'.$this->Relative_Path($event).'/'.$event['DefaultVideo']) ) {
|
||||
return 1;
|
||||
} else {
|
||||
Logger::Debug("FIle does not exist at " . $storage['Storage']['Path'].'/'.$this->Relative_Path($event).'/'.$event['DefaultVideo'] );
|
||||
|
@ -130,5 +130,10 @@ class Event extends AppModel {
|
|||
Logger::Debug("No DefaultVideo in Event" . $this->Event);
|
||||
return 0;
|
||||
}
|
||||
} // end function fileExists($event)
|
||||
|
||||
public function fileSize($event) {
|
||||
$storage = $this->Storage->findById($event['StorageId']);
|
||||
return filesize($storage['Storage']['Path'].'/'.$this->Relative_Path($event).'/'.$event['DefaultVideo']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit ca91b87fda8e006e4fca2ed870f24f9a29c2905d
|
||||
Subproject commit ea90c0cd7f6e24333a90885e563b5d30b793db29
|
|
@ -1 +1 @@
|
|||
Subproject commit c3976f1478c681b0bbc132ec3a3e82c3984eeed5
|
||||
Subproject commit 0bd63fb464957080ead342db58ca9e01532cf1ef
|
|
@ -10,9 +10,31 @@ class Event {
|
|||
'MonitorId',
|
||||
'StorageId',
|
||||
'Name',
|
||||
'DiskSpace',
|
||||
'Cause',
|
||||
'StartTime',
|
||||
'EndTime',
|
||||
'Width',
|
||||
'Height',
|
||||
'Length',
|
||||
'Frames',
|
||||
'AlarmFrames',
|
||||
'DefaultVideo',
|
||||
'SaveJPEGs',
|
||||
'TotScore',
|
||||
'AvgScore',
|
||||
'MaxScore',
|
||||
'Archived',
|
||||
'Videoed',
|
||||
'Uploaded',
|
||||
'Emailed',
|
||||
'Messaged',
|
||||
'Executed',
|
||||
'Notes',
|
||||
'StateId',
|
||||
'Orientation',
|
||||
'DiskSpace',
|
||||
'Scheme',
|
||||
'Locked',
|
||||
);
|
||||
public function __construct( $IdOrRow = null ) {
|
||||
$row = NULL;
|
||||
|
@ -566,6 +588,50 @@ class Event {
|
|||
return false;
|
||||
} # end public function file_exists()
|
||||
|
||||
public function file_size() {
|
||||
if ( file_exists($this->Path().'/'.$this->DefaultVideo()) ) {
|
||||
return filesize($this->Path().'/'.$this->DefaultVideo());
|
||||
}
|
||||
$Storage= $this->Storage();
|
||||
$Server = $Storage->ServerId() ? $Storage->Server() : $this->Monitor()->Server();
|
||||
if ( $Server->Id() != ZM_SERVER_ID ) {
|
||||
|
||||
$url = $Server->Url() . '/zm/api/events/'.$this->{'Id'}.'.json';
|
||||
if ( ZM_OPT_USE_AUTH ) {
|
||||
if ( ZM_AUTH_RELAY == 'hashed' ) {
|
||||
$url .= '?auth='.generateAuthHash( ZM_AUTH_HASH_IPS );
|
||||
} elseif ( ZM_AUTH_RELAY == 'plain' ) {
|
||||
$url = '?user='.$_SESSION['username'];
|
||||
$url = '?pass='.$_SESSION['password'];
|
||||
} elseif ( ZM_AUTH_RELAY == 'none' ) {
|
||||
$url = '?user='.$_SESSION['username'];
|
||||
}
|
||||
}
|
||||
Logger::Debug("sending command to $url");
|
||||
// use key 'http' even if you send the request to https://...
|
||||
$options = array(
|
||||
'http' => array(
|
||||
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
|
||||
'method' => 'GET',
|
||||
'content' => ''
|
||||
)
|
||||
);
|
||||
$context = stream_context_create($options);
|
||||
try {
|
||||
$result = file_get_contents($url, false, $context);
|
||||
if ($result === FALSE) { /* Handle error */
|
||||
Error("Error restarting zmc using $url");
|
||||
}
|
||||
$event_data = json_decode($result,true);
|
||||
Logger::Debug(print_r($event_data['event']['Event'],1));
|
||||
return $event_data['event']['Event']['fileSize'];
|
||||
} catch ( Exception $e ) {
|
||||
Error("Except $e thrown trying to get event data");
|
||||
}
|
||||
} # end if not local
|
||||
return 0;
|
||||
} # end public function file_size()
|
||||
|
||||
} # end class
|
||||
|
||||
?>
|
||||
|
|
|
@ -20,7 +20,7 @@ public $defaults = array(
|
|||
'limit' => 100,
|
||||
'Query' => array(),
|
||||
'sort_field' => ZM_WEB_EVENT_SORT_FIELD,
|
||||
'sort_asc' => (ZM_WEB_EVENT_SORT_ORDER == 'asc' ? 'asc' : 'desc'),
|
||||
'sort_asc' => ZM_WEB_EVENT_SORT_ORDER,
|
||||
);
|
||||
|
||||
public function __construct( $IdOrRow=NULL ) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
require_once( 'database.php' );
|
||||
require_once( 'Server.php' );
|
||||
require_once('database.php');
|
||||
require_once('Server.php');
|
||||
|
||||
class Monitor {
|
||||
|
||||
|
@ -130,12 +130,12 @@ private $control_fields = array(
|
|||
public function __construct( $IdOrRow = NULL ) {
|
||||
if ( $IdOrRow ) {
|
||||
$row = NULL;
|
||||
if ( is_integer( $IdOrRow ) or is_numeric( $IdOrRow ) ) {
|
||||
$row = dbFetchOne( 'SELECT * FROM Monitors WHERE Id=?', NULL, array( $IdOrRow ) );
|
||||
if ( is_integer($IdOrRow) or is_numeric($IdOrRow) ) {
|
||||
$row = dbFetchOne('SELECT * FROM Monitors WHERE Id=?', NULL, array($IdOrRow));
|
||||
if ( ! $row ) {
|
||||
Error("Unable to load Monitor record for Id=" . $IdOrRow );
|
||||
Error("Unable to load Monitor record for Id=" . $IdOrRow);
|
||||
}
|
||||
} elseif ( is_array( $IdOrRow ) ) {
|
||||
} elseif ( is_array($IdOrRow) ) {
|
||||
$row = $IdOrRow;
|
||||
} else {
|
||||
Error("Unknown argument passed to Monitor Constructor ($IdOrRow)");
|
||||
|
@ -147,7 +147,7 @@ private $control_fields = array(
|
|||
$this->{$k} = $v;
|
||||
}
|
||||
if ( $this->{'Controllable'} ) {
|
||||
$s = dbFetchOne( 'SELECT * FROM Controls WHERE Id=?', NULL, array( $this->{'ControlId'} ) );
|
||||
$s = dbFetchOne('SELECT * FROM Controls WHERE Id=?', NULL, array($this->{'ControlId'}) );
|
||||
foreach ($s as $k => $v) {
|
||||
if ( $k == 'Id' ) {
|
||||
continue;
|
||||
|
@ -165,13 +165,13 @@ private $control_fields = array(
|
|||
}
|
||||
|
||||
} else {
|
||||
Error('No row for Monitor ' . $IdOrRow );
|
||||
Error('No row for Monitor ' . $IdOrRow);
|
||||
}
|
||||
} # end if isset($IdOrRow)
|
||||
} // end function __construct
|
||||
|
||||
public function Server() {
|
||||
return new Server( $this->{'ServerId'} );
|
||||
return new Server($this->{'ServerId'});
|
||||
}
|
||||
public function __call($fn, array $args){
|
||||
if ( count($args) ) {
|
||||
|
@ -235,24 +235,25 @@ private $control_fields = array(
|
|||
return( $streamSrc );
|
||||
} // end function getStreamSrc
|
||||
|
||||
public function Width( $new = null ) {
|
||||
public function Width($new = null) {
|
||||
if ( $new )
|
||||
$this->{'Width'} = $new;
|
||||
|
||||
if ( $this->Orientation() == '90' or $this->Orientation() == '270' ) {
|
||||
return $this->{'Height'};
|
||||
}
|
||||
return $this->{'Width'};
|
||||
}
|
||||
$field = ( $this->Orientation() == '90' or $this->Orientation() == '270' ) ? 'Height' : 'Width';
|
||||
if ( array_key_exists($field, $this) )
|
||||
return $this->{$field};
|
||||
return $this->defaults{$field};
|
||||
} // end function Width
|
||||
|
||||
public function Height( $new=null ) {
|
||||
public function Height($new=null) {
|
||||
if ( $new )
|
||||
$this->{'Height'} = $new;
|
||||
if ( $this->Orientation() == '90' or $this->Orientation() == '270' ) {
|
||||
return $this->{'Width'};
|
||||
}
|
||||
return $this->{'Height'};
|
||||
}
|
||||
|
||||
$field = ( $this->Orientation() == '90' or $this->Orientation() == '270' ) ? 'Width' : 'Height';
|
||||
if ( array_key_exists($field, $this) )
|
||||
return $this->{$field};
|
||||
return $this->defaults{$field};
|
||||
} // end function Height
|
||||
|
||||
public function set($data) {
|
||||
foreach ($data as $k => $v) {
|
||||
|
@ -334,13 +335,13 @@ private $control_fields = array(
|
|||
}
|
||||
|
||||
if ( $mode == 'stop' ) {
|
||||
daemonControl( 'stop', 'zmc', $zmcArgs );
|
||||
daemonControl('stop', 'zmc', $zmcArgs);
|
||||
} else {
|
||||
if ( $mode == 'restart' ) {
|
||||
daemonControl( 'stop', 'zmc', $zmcArgs );
|
||||
daemonControl('stop', 'zmc', $zmcArgs);
|
||||
}
|
||||
if ( $this->{'Function'} != 'None' ) {
|
||||
daemonControl( 'start', 'zmc', $zmcArgs );
|
||||
daemonControl('start', 'zmc', $zmcArgs);
|
||||
}
|
||||
}
|
||||
} else if ( $this->ServerId() ) {
|
||||
|
@ -377,6 +378,8 @@ private $control_fields = array(
|
|||
} catch ( Exception $e ) {
|
||||
Error("Except $e thrown trying to restart zmc");
|
||||
}
|
||||
} else {
|
||||
Error("Server not assigned to Monitor in a multi-server setup. Please assign a server to the Monitor.");
|
||||
}
|
||||
} // end function zmcControl
|
||||
|
||||
|
@ -384,9 +387,9 @@ private $control_fields = array(
|
|||
if ( (!defined('ZM_SERVER_ID')) or ( array_key_exists('ServerId', $this) and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) {
|
||||
if ( $this->{'Function'} == 'None' || $this->{'Function'} == 'Monitor' || $mode == 'stop' ) {
|
||||
if ( ZM_OPT_CONTROL ) {
|
||||
daemonControl( 'stop', 'zmtrack.pl', '-m '.$this->{'Id'} );
|
||||
daemonControl('stop', 'zmtrack.pl', '-m '.$this->{'Id'});
|
||||
}
|
||||
daemonControl( 'stop', 'zma', '-m '.$this->{'Id'} );
|
||||
daemonControl('stop', 'zma', '-m '.$this->{'Id'});
|
||||
} else {
|
||||
if ( $mode == 'restart' ) {
|
||||
if ( ZM_OPT_CONTROL ) {
|
||||
|
@ -403,7 +406,8 @@ private $control_fields = array(
|
|||
}
|
||||
}
|
||||
} // end if we are on the recording server
|
||||
}
|
||||
} // end public function zmaControl
|
||||
|
||||
public function GroupIds( $new='') {
|
||||
if ( $new != '' ) {
|
||||
if(!is_array($new)) {
|
||||
|
@ -464,6 +468,8 @@ private $control_fields = array(
|
|||
$this->{'Storage'} = isset($this->{'StorageId'}) ?
|
||||
Storage::find_one(array('Id'=>$this->{'StorageId'})) :
|
||||
new Storage(NULL);
|
||||
if ( ! $this->{'Storage'} )
|
||||
$this->{'Storage'} = new Storage(NULL);
|
||||
}
|
||||
return $this->{'Storage'};
|
||||
}
|
||||
|
@ -483,9 +489,9 @@ private $control_fields = array(
|
|||
$url_parts = parse_url( $this->{'Path'} );
|
||||
unset($url_parts['user']);
|
||||
unset($url_parts['pass']);
|
||||
unset($url_parts['scheme']);
|
||||
#unset($url_parts['scheme']);
|
||||
unset($url_parts['query']);
|
||||
unset($url_parts['path']);
|
||||
#unset($url_parts['path']);
|
||||
if ( isset($url_parts['port']) and ( $url_parts['port'] == '80' or $url_parts['port'] == '554' ) )
|
||||
unset($url_parts['port']);
|
||||
$source = unparse_url($url_parts);
|
||||
|
|
|
@ -476,15 +476,12 @@ if ( canEdit( 'Monitors' ) ) {
|
|||
);
|
||||
|
||||
if ( $_REQUEST['newMonitor']['ServerId'] == 'auto' ) {
|
||||
Logger::Debug("Auto selecting server");
|
||||
$_REQUEST['newMonitor']['ServerId'] = dbFetchOne('SELECT Id FROM Servers WHERE Status=\'Running\' ORDER BY FreeMem DESC, CpuLoad ASC LIMIT 1', 'Id');
|
||||
Logger::Debug("Auto selecting server: Got " . $_REQUEST['newMonitor']['ServerId'] );
|
||||
if ( ( ! $_REQUEST['newMonitor'] ) and defined('ZM_SERVER_ID') ) {
|
||||
$_REQUEST['newMonitor']['ServerId'] = ZM_SERVER_ID;
|
||||
Logger::Debug("Auto selecting server to " . ZM_SERVER_ID);
|
||||
}
|
||||
} else {
|
||||
Logger::Debug("NOT Auto selecting server" . $_REQUEST['newMonitor']['ServerId']);
|
||||
}
|
||||
|
||||
$columns = getTableColumns('Monitors');
|
||||
|
@ -495,8 +492,8 @@ if ( canEdit( 'Monitors' ) ) {
|
|||
|
||||
# If we change anything that changes the shared mem size, zma can complain. So let's stop first.
|
||||
if ( $monitor['Type'] != 'WebSite' ) {
|
||||
zmaControl( $monitor, 'stop' );
|
||||
zmcControl( $monitor, 'stop' );
|
||||
zmaControl($monitor, 'stop');
|
||||
zmcControl($monitor, 'stop');
|
||||
}
|
||||
dbQuery( 'UPDATE Monitors SET '.implode( ', ', $changes ).' WHERE Id=?', array($mid) );
|
||||
// Groups will be added below
|
||||
|
@ -570,23 +567,26 @@ if ( canEdit( 'Monitors' ) ) {
|
|||
}
|
||||
|
||||
$restart = true;
|
||||
} else {
|
||||
Logger::Debug("No action due to no changes to Monitor");
|
||||
} # end if count(changes)
|
||||
if (
|
||||
( !isset($_POST['newMonitor']['GroupIds']) )
|
||||
or
|
||||
( count($_POST['newMonitor']['GroupIds']) != count($Monitor->GroupIds()) )
|
||||
or
|
||||
array_diff($_POST['newMonitor']['GroupIds'], $Monitor->GroupIds())
|
||||
) {
|
||||
if ( $Monitor->Id() )
|
||||
dbQuery('DELETE FROM Groups_Monitors WHERE MonitorId=?', array($mid));
|
||||
|
||||
if ( isset($_POST['newMonitor']['GroupIds']) ) {
|
||||
foreach ( $_POST['newMonitor']['GroupIds'] as $group_id ) {
|
||||
dbQuery('INSERT INTO Groups_Monitors (GroupId,MonitorId) VALUES (?,?)', array($group_id, $mid));
|
||||
}
|
||||
if (
|
||||
( !isset($_POST['newMonitor']['GroupIds']) )
|
||||
or
|
||||
( count($_POST['newMonitor']['GroupIds']) != count($Monitor->GroupIds()) )
|
||||
or
|
||||
array_diff($_POST['newMonitor']['GroupIds'], $Monitor->GroupIds())
|
||||
) {
|
||||
if ( $Monitor->Id() )
|
||||
dbQuery('DELETE FROM Groups_Monitors WHERE MonitorId=?', array($mid));
|
||||
|
||||
if ( isset($_POST['newMonitor']['GroupIds']) ) {
|
||||
foreach ( $_POST['newMonitor']['GroupIds'] as $group_id ) {
|
||||
dbQuery('INSERT INTO Groups_Monitors (GroupId,MonitorId) VALUES (?,?)', array($group_id, $mid));
|
||||
}
|
||||
} // end if there has been a change of groups
|
||||
}
|
||||
} // end if there has been a change of groups
|
||||
|
||||
if ( ZM_OPT_X10 ) {
|
||||
$x10Changes = getFormChanges( $x10Monitor, $_REQUEST['newX10Monitor'] );
|
||||
|
|
|
@ -355,7 +355,7 @@ function getEventDefaultVideoPath( $event ) {
|
|||
function deletePath( $path ) {
|
||||
if ( is_dir( $path ) ) {
|
||||
system( escapeshellcmd( 'rm -rf '.$path ) );
|
||||
} else {
|
||||
} else if ( file_exists($path) ) {
|
||||
unlink( $path );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -200,7 +200,7 @@ isset($view) || $view = NULL;
|
|||
isset($request) || $request = NULL;
|
||||
isset($action) || $action = NULL;
|
||||
|
||||
if ( ZM_ENABLE_CSRF_MAGIC && $action != 'login' && $view != 'view_video' && $view != 'video' && $request != 'control' && $view != 'frames') {
|
||||
if ( ZM_ENABLE_CSRF_MAGIC && $action != 'login' && $view != 'view_video' && $request != 'control' && $view != 'frames' && $view != 'archive' ) {
|
||||
require_once( 'includes/csrf/csrf-magic.php' );
|
||||
#Logger::Debug("Calling csrf_check with the following values: \$request = \"$request\", \$view = \"$view\", \$action = \"$action\"");
|
||||
csrf_check();
|
||||
|
|
|
@ -38,13 +38,6 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
#dvrControls input {
|
||||
height: 20px;
|
||||
width: 28px;
|
||||
padding-bottom: 3px;
|
||||
margin: 0 3px;
|
||||
}
|
||||
|
||||
#dvrControls input[disabled] {
|
||||
color: #aaaaaa;
|
||||
}
|
||||
|
|
|
@ -18,126 +18,113 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
function getControlCommands( $monitor )
|
||||
{
|
||||
$cmds = array();
|
||||
function getControlCommands( $monitor ) {
|
||||
$cmds = array();
|
||||
|
||||
$cmds['Wake'] = "wake";
|
||||
$cmds['Sleep'] = "sleep";
|
||||
$cmds['Reset'] = "reset";
|
||||
$cmds['Wake'] = "wake";
|
||||
$cmds['Sleep'] = "sleep";
|
||||
$cmds['Reset'] = "reset";
|
||||
|
||||
$cmds['PresetSet'] = "presetSet";
|
||||
$cmds['PresetGoto'] = "presetGoto";
|
||||
$cmds['PresetHome'] = "presetHome";
|
||||
$cmds['PresetSet'] = "presetSet";
|
||||
$cmds['PresetGoto'] = "presetGoto";
|
||||
$cmds['PresetHome'] = "presetHome";
|
||||
|
||||
if ( $monitor->CanZoom() )
|
||||
{
|
||||
if ( $monitor->CanZoomCon() )
|
||||
$cmds['ZoomRoot'] = "zoomCon";
|
||||
elseif ( $monitor->CanZoomRel() )
|
||||
$cmds['ZoomRoot'] = "zoomRel";
|
||||
elseif ( $monitor->CanZoomAbs() )
|
||||
$cmds['ZoomRoot'] = "zoomAbs";
|
||||
$cmds['ZoomTele'] = $cmds['ZoomRoot']."Tele";
|
||||
$cmds['ZoomWide'] = $cmds['ZoomRoot']."Wide";
|
||||
$cmds['ZoomStop'] = "zoomStop";
|
||||
$cmds['ZoomAuto'] = "zoomAuto";
|
||||
$cmds['ZoomMan'] = "zoomMan";
|
||||
if ( $monitor->CanZoom() ) {
|
||||
if ( $monitor->CanZoomCon() )
|
||||
$cmds['ZoomRoot'] = "zoomCon";
|
||||
elseif ( $monitor->CanZoomRel() )
|
||||
$cmds['ZoomRoot'] = "zoomRel";
|
||||
elseif ( $monitor->CanZoomAbs() )
|
||||
$cmds['ZoomRoot'] = "zoomAbs";
|
||||
$cmds['ZoomTele'] = $cmds['ZoomRoot']."Tele";
|
||||
$cmds['ZoomWide'] = $cmds['ZoomRoot']."Wide";
|
||||
$cmds['ZoomStop'] = "zoomStop";
|
||||
$cmds['ZoomAuto'] = "zoomAuto";
|
||||
$cmds['ZoomMan'] = "zoomMan";
|
||||
}
|
||||
|
||||
if ( $monitor->CanFocus() ) {
|
||||
if ( $monitor->CanFocusCon() )
|
||||
$cmds['FocusRoot'] = "focusCon";
|
||||
elseif ( $monitor->CanFocusRel() )
|
||||
$cmds['FocusRoot'] = "focusRel";
|
||||
elseif ( $monitor->CanFocusAbs() )
|
||||
$cmds['FocusRoot'] = "focusAbs";
|
||||
$cmds['FocusFar'] = $cmds['FocusRoot']."Far";
|
||||
$cmds['FocusNear'] = $cmds['FocusRoot']."Near";
|
||||
$cmds['FocusStop'] = "focusStop";
|
||||
$cmds['FocusAuto'] = "focusAuto";
|
||||
$cmds['FocusMan'] = "focusMan";
|
||||
}
|
||||
|
||||
if ( $monitor->CanIris() ) {
|
||||
if ( $monitor->CanIrisCon() )
|
||||
$cmds['IrisRoot'] = "irisCon";
|
||||
elseif ( $monitor->CanIrisRel() )
|
||||
$cmds['IrisRoot'] = "irisRel";
|
||||
elseif ( $monitor->CanIrisAbs() )
|
||||
$cmds['IrisRoot'] = "irisAbs";
|
||||
$cmds['IrisOpen'] = $cmds['IrisRoot']."Open";
|
||||
$cmds['IrisClose'] = $cmds['IrisRoot']."Close";
|
||||
$cmds['IrisStop'] = "irisStop";
|
||||
$cmds['IrisAuto'] = "irisAuto";
|
||||
$cmds['IrisMan'] = "irisMan";
|
||||
}
|
||||
|
||||
if ( $monitor->CanWhite() ) {
|
||||
if ( $monitor->CanWhiteCon() )
|
||||
$cmds['WhiteRoot'] = "whiteCon";
|
||||
elseif ( $monitor->CanWhiteRel() )
|
||||
$cmds['WhiteRoot'] = "whiteRel";
|
||||
elseif ( $monitor->CanWhiteAbs() )
|
||||
$cmds['WhiteRoot'] = "whiteAbs";
|
||||
$cmds['WhiteIn'] = $cmds['WhiteRoot']."In";
|
||||
$cmds['WhiteOut'] = $cmds['WhiteRoot']."Out";
|
||||
$cmds['WhiteAuto'] = "whiteAuto";
|
||||
$cmds['WhiteMan'] = "whiteMan";
|
||||
}
|
||||
|
||||
if ( $monitor->CanGain() ) {
|
||||
if ( $monitor->CanGainCon() )
|
||||
$cmds['GainRoot'] = "gainCon";
|
||||
elseif ( $monitor->CanGainRel() )
|
||||
$cmds['GainRoot'] = "gainRel";
|
||||
elseif ( $monitor->CanGainAbs() )
|
||||
$cmds['GainRoot'] = "gainAbs";
|
||||
$cmds['GainUp'] = $cmds['GainRoot']."Up";
|
||||
$cmds['GainDown'] = $cmds['GainRoot']."Down";
|
||||
$cmds['GainAuto'] = "gainAuto";
|
||||
$cmds['GainMan'] = "gainMan";
|
||||
}
|
||||
|
||||
if ( $monitor->CanMove() ) {
|
||||
if ( $monitor->CanMoveCon() ) {
|
||||
$cmds['MoveRoot'] = "moveCon";
|
||||
$cmds['Center'] = "moveStop";
|
||||
} elseif ( $monitor->CanMoveRel() ) {
|
||||
$cmds['MoveRoot'] = "moveRel";
|
||||
$cmds['Center'] = $cmds['PresetHome'];
|
||||
} elseif ( $monitor->CanMoveAbs() ) {
|
||||
$cmds['MoveRoot'] = "moveAbs";
|
||||
$cmds['Center'] = $cmds['PresetHome'];
|
||||
} else {
|
||||
$cmds['MoveRoot'] = '';
|
||||
}
|
||||
|
||||
if ( $monitor->CanFocus() )
|
||||
{
|
||||
if ( $monitor->CanFocusCon() )
|
||||
$cmds['FocusRoot'] = "focusCon";
|
||||
elseif ( $monitor->CanFocusRel() )
|
||||
$cmds['FocusRoot'] = "focusRel";
|
||||
elseif ( $monitor->CanFocusAbs() )
|
||||
$cmds['FocusRoot'] = "focusAbs";
|
||||
$cmds['FocusFar'] = $cmds['FocusRoot']."Far";
|
||||
$cmds['FocusNear'] = $cmds['FocusRoot']."Near";
|
||||
$cmds['FocusStop'] = "focusStop";
|
||||
$cmds['FocusAuto'] = "focusAuto";
|
||||
$cmds['FocusMan'] = "focusMan";
|
||||
}
|
||||
|
||||
if ( $monitor->CanIris() )
|
||||
{
|
||||
if ( $monitor->CanIrisCon() )
|
||||
$cmds['IrisRoot'] = "irisCon";
|
||||
elseif ( $monitor->CanIrisRel() )
|
||||
$cmds['IrisRoot'] = "irisRel";
|
||||
elseif ( $monitor->CanIrisAbs() )
|
||||
$cmds['IrisRoot'] = "irisAbs";
|
||||
$cmds['IrisOpen'] = $cmds['IrisRoot']."Open";
|
||||
$cmds['IrisClose'] = $cmds['IrisRoot']."Close";
|
||||
$cmds['IrisStop'] = "irisStop";
|
||||
$cmds['IrisAuto'] = "irisAuto";
|
||||
$cmds['IrisMan'] = "irisMan";
|
||||
}
|
||||
|
||||
if ( $monitor->CanWhite() )
|
||||
{
|
||||
if ( $monitor->CanWhiteCon() )
|
||||
$cmds['WhiteRoot'] = "whiteCon";
|
||||
elseif ( $monitor->CanWhiteRel() )
|
||||
$cmds['WhiteRoot'] = "whiteRel";
|
||||
elseif ( $monitor->CanWhiteAbs() )
|
||||
$cmds['WhiteRoot'] = "whiteAbs";
|
||||
$cmds['WhiteIn'] = $cmds['WhiteRoot']."In";
|
||||
$cmds['WhiteOut'] = $cmds['WhiteRoot']."Out";
|
||||
$cmds['WhiteAuto'] = "whiteAuto";
|
||||
$cmds['WhiteMan'] = "whiteMan";
|
||||
}
|
||||
|
||||
if ( $monitor->CanGain() )
|
||||
{
|
||||
if ( $monitor->CanGainCon() )
|
||||
$cmds['GainRoot'] = "gainCon";
|
||||
elseif ( $monitor->CanGainRel() )
|
||||
$cmds['GainRoot'] = "gainRel";
|
||||
elseif ( $monitor->CanGainAbs() )
|
||||
$cmds['GainRoot'] = "gainAbs";
|
||||
$cmds['GainUp'] = $cmds['GainRoot']."Up";
|
||||
$cmds['GainDown'] = $cmds['GainRoot']."Down";
|
||||
$cmds['GainAuto'] = "gainAuto";
|
||||
$cmds['GainMan'] = "gainMan";
|
||||
}
|
||||
|
||||
if ( $monitor->CanMove() )
|
||||
{
|
||||
if ( $monitor->CanMoveCon() )
|
||||
{
|
||||
$cmds['MoveRoot'] = "moveCon";
|
||||
$cmds['Center'] = "moveStop";
|
||||
}
|
||||
elseif ( $monitor->CanMoveRel() )
|
||||
{
|
||||
$cmds['MoveRoot'] = "moveRel";
|
||||
$cmds['Center'] = $cmds['PresetHome'];
|
||||
}
|
||||
elseif ( $monitor->CanMoveAbs() )
|
||||
{
|
||||
$cmds['MoveRoot'] = "moveAbs";
|
||||
$cmds['Center'] = $cmds['PresetHome'];
|
||||
} else {
|
||||
$cmds['MoveRoot'] = '';
|
||||
}
|
||||
|
||||
$cmds['MoveUp'] = $cmds['MoveRoot']."Up";
|
||||
$cmds['MoveDown'] = $cmds['MoveRoot']."Down";
|
||||
$cmds['MoveLeft'] = $cmds['MoveRoot']."Left";
|
||||
$cmds['MoveRight'] = $cmds['MoveRoot']."Right";
|
||||
$cmds['MoveUpLeft'] = $cmds['MoveRoot']."UpLeft";
|
||||
$cmds['MoveUpRight'] = $cmds['MoveRoot']."UpRight";
|
||||
$cmds['MoveDownLeft'] = $cmds['MoveRoot']."DownLeft";
|
||||
$cmds['MoveDownRight'] = $cmds['MoveRoot']."DownRight";
|
||||
}
|
||||
return( $cmds );
|
||||
$cmds['MoveUp'] = $cmds['MoveRoot']."Up";
|
||||
$cmds['MoveDown'] = $cmds['MoveRoot']."Down";
|
||||
$cmds['MoveLeft'] = $cmds['MoveRoot']."Left";
|
||||
$cmds['MoveRight'] = $cmds['MoveRoot']."Right";
|
||||
$cmds['MoveUpLeft'] = $cmds['MoveRoot']."UpLeft";
|
||||
$cmds['MoveUpRight'] = $cmds['MoveRoot']."UpRight";
|
||||
$cmds['MoveDownLeft'] = $cmds['MoveRoot']."DownLeft";
|
||||
$cmds['MoveDownRight'] = $cmds['MoveRoot']."DownRight";
|
||||
}
|
||||
return( $cmds );
|
||||
}
|
||||
|
||||
function controlFocus( $monitor, $cmds )
|
||||
{
|
||||
ob_start();
|
||||
function controlFocus( $monitor, $cmds ) {
|
||||
ob_start();
|
||||
?>
|
||||
<div class="arrowControl focusControls">
|
||||
<div class="arrowLabel"><?php echo translate('Near') ?></div>
|
||||
|
@ -146,24 +133,22 @@ function controlFocus( $monitor, $cmds )
|
|||
<div class="longArrowBtn downBtn" onclick="controlCmd('<?php echo $cmds['FocusFar'] ?>',event,0,1)"></div>
|
||||
<div class="arrowLabel"><?php echo translate('Far') ?></div>
|
||||
<?php
|
||||
if ( $monitor->CanAutoFocus() )
|
||||
{
|
||||
if ( $monitor->CanAutoFocus() ) {
|
||||
?>
|
||||
<input type="button" class="ptzTextBtn" value="<?php echo translate('Auto') ?>" onclick="controlCmd('<?php echo $cmds['FocusAuto'] ?>')"/>
|
||||
<input type="button" class="ptzTextBtn" value="<?php echo translate('Man') ?>" onclick="controlCmd('<?php echo $cmds['FocusMan'] ?>')"/>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
return( ob_get_clean() );
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
function controlZoom( $monitor, $cmds )
|
||||
{
|
||||
global $SLANG;
|
||||
function controlZoom( $monitor, $cmds ) {
|
||||
global $SLANG;
|
||||
|
||||
ob_start();
|
||||
ob_start();
|
||||
?>
|
||||
<div class="arrowControl zoomControls">
|
||||
<div class="arrowLabel"><?php echo translate('Tele') ?></div>
|
||||
|
@ -172,23 +157,21 @@ function controlZoom( $monitor, $cmds )
|
|||
<div class="longArrowBtn downBtn" onclick="controlCmd('<?php echo $cmds['ZoomWide'] ?>',event,0,1)"></div>
|
||||
<div class="arrowLabel"><?php echo translate('Wide') ?></div>
|
||||
<?php
|
||||
if ( $monitor->CanAutoZoom() )
|
||||
{
|
||||
if ( $monitor->CanAutoZoom() ) {
|
||||
?>
|
||||
<input type="button" class="ptzTextBtn" value="<?php echo translate('Auto') ?>" onclick="controlCmd('<?php echo $cmds['ZoomAuto'] ?>')"/>
|
||||
<input type="button" class="ptzTextBtn" value="<?php echo translate('Man') ?>" onclick="controlCmd('<?php echo $cmds['ZoomMan'] ?>')"/>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div><?php
|
||||
return( ob_get_clean() );
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
function controlIris( $monitor, $cmds )
|
||||
{
|
||||
global $SLANG;
|
||||
function controlIris( $monitor, $cmds ) {
|
||||
global $SLANG;
|
||||
|
||||
ob_start();
|
||||
ob_start();
|
||||
?>
|
||||
<div class="arrowControl irisControls">
|
||||
<div class="arrowLabel"><?php echo translate('Open') ?></div>
|
||||
|
@ -197,24 +180,22 @@ function controlIris( $monitor, $cmds )
|
|||
<div class="longArrowBtn downBtn" onclick="controlCmd('<?php echo $cmds['IrisClose'] ?>',event,0,1)"></div>
|
||||
<div class="arrowLabel"><?php echo translate('Close') ?></div>
|
||||
<?php
|
||||
if ( $monitor->CanAutoIris() )
|
||||
{
|
||||
if ( $monitor->CanAutoIris() ) {
|
||||
?>
|
||||
<input type="button" class="ptzTextBtn" value="<?php echo translate('Auto') ?>" onclick="controlCmd('<?php echo $cmds['IrisAuto'] ?>')"/>
|
||||
<input type="button" class="ptzTextBtn" value="<?php echo translate('Man') ?>" onclick="controlCmd('<?php echo $cmds['IrisMan'] ?>')"/>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
return( ob_get_clean() );
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
function controlWhite( $monitor, $cmds )
|
||||
{
|
||||
global $SLANG;
|
||||
function controlWhite( $monitor, $cmds ) {
|
||||
global $SLANG;
|
||||
|
||||
ob_start();
|
||||
ob_start();
|
||||
?>
|
||||
<div class="arrowControl whiteControls">
|
||||
<div class="arrowLabel"><?php echo translate('In') ?></div>
|
||||
|
@ -223,170 +204,158 @@ function controlWhite( $monitor, $cmds )
|
|||
<div class="longArrowBtn downBtn" onclick="controlCmd('<?php echo $cmds['WhiteOut'] ?>',event,0,1)"></div>
|
||||
<div class="arrowLabel"><?php echo translate('Out') ?></div>
|
||||
<?php
|
||||
if ( $monitor->CanAutoWhite() )
|
||||
{
|
||||
if ( $monitor->CanAutoWhite() ) {
|
||||
?>
|
||||
<input type="button" class="ptzTextBtn" value="<?php echo translate('Auto') ?>" onclick="controlCmd('<?php echo $cmds['WhiteAuto'] ?>')"/>
|
||||
<input type="button" class="ptzTextBtn" value="<?php echo translate('Man') ?>" onclick="controlCmd('<?php echo $cmds['WhiteMan'] ?>')"/>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
return( ob_get_clean() );
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
function controlPanTilt( $monitor, $cmds )
|
||||
{
|
||||
global $SLANG;
|
||||
function controlPanTilt( $monitor, $cmds ) {
|
||||
global $SLANG;
|
||||
|
||||
ob_start();
|
||||
ob_start();
|
||||
?>
|
||||
<div class="pantiltControls">
|
||||
<div class="pantiltLabel"><?php echo translate('PanTilt') ?></div>
|
||||
<div class="pantiltButtons">
|
||||
<?php
|
||||
$hasPan = $monitor->CanPan();
|
||||
$hasTilt = $monitor->CanTilt();
|
||||
$hasDiag = $hasPan && $hasTilt && $monitor->CanMoveDiag();
|
||||
$hasPan = $monitor->CanPan();
|
||||
$hasTilt = $monitor->CanTilt();
|
||||
$hasDiag = $hasPan && $hasTilt && $monitor->CanMoveDiag();
|
||||
?>
|
||||
<div class="arrowBtn upLeftBtn<?php echo $hasDiag?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveUpLeft'] ?>',event,-1,-1)"></div>
|
||||
<div class="arrowBtn upBtn<?php echo $hasTilt?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveUp'] ?>',event,0,-1)"></div>
|
||||
<div class="arrowBtn upRightBtn<?php echo $hasDiag?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveUpRight'] ?>',event,1,-1)"></div>
|
||||
<div class="arrowBtn leftBtn<?php echo $hasPan?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveLeft'] ?>',event,1,0)"></div>
|
||||
<div class="arrowBtn upLeftBtn<?php echo $hasDiag?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveUpLeft'] ?>',event,-1,-1)"></div>
|
||||
<div class="arrowBtn upBtn<?php echo $hasTilt?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveUp'] ?>',event,0,-1)"></div>
|
||||
<div class="arrowBtn upRightBtn<?php echo $hasDiag?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveUpRight'] ?>',event,1,-1)"></div>
|
||||
<div class="arrowBtn leftBtn<?php echo $hasPan?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveLeft'] ?>',event,1,0)"></div>
|
||||
<?php if ( isset($cmds['Center']) ) { ?>
|
||||
<div class="arrowBtn centerBtn" onclick="controlCmd('<?php echo $cmds['Center'] ?>')"></div>
|
||||
<div class="arrowBtn centerBtn" onclick="controlCmd('<?php echo $cmds['Center'] ?>')"></div>
|
||||
<?php } else { ?>
|
||||
<div class="arrowBtn NocenterBtn"></div>
|
||||
<div class="arrowBtn NocenterBtn"></div>
|
||||
<?php } ?>
|
||||
<div class="arrowBtn rightBtn<?php echo $hasPan?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveRight'] ?>',event,1,0)"></div>
|
||||
<div class="arrowBtn downLeftBtn<?php echo $hasDiag?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveDownLeft'] ?>',event,-1,1)"></div>
|
||||
<div class="arrowBtn downBtn<?php echo $hasTilt?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveDown'] ?>',event,0,1)"></div>
|
||||
<div class="arrowBtn downRightBtn<?php echo $hasDiag?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveDownRight'] ?>',event,1,1)"></div>
|
||||
<div class="arrowBtn rightBtn<?php echo $hasPan?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveRight'] ?>',event,1,0)"></div>
|
||||
<div class="arrowBtn downLeftBtn<?php echo $hasDiag?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveDownLeft'] ?>',event,-1,1)"></div>
|
||||
<div class="arrowBtn downBtn<?php echo $hasTilt?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveDown'] ?>',event,0,1)"></div>
|
||||
<div class="arrowBtn downRightBtn<?php echo $hasDiag?'':' invisible' ?>" onclick="controlCmd('<?php echo $cmds['MoveDownRight'] ?>',event,1,1)"></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
return( ob_get_clean() );
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
function controlPresets( $monitor, $cmds )
|
||||
{
|
||||
global $SLANG;
|
||||
function controlPresets( $monitor, $cmds ) {
|
||||
global $SLANG;
|
||||
|
||||
define( "MAX_PRESETS", "12" );
|
||||
// MAX_PRESETS IS PER LINE
|
||||
define( "MAX_PRESETS", "12" );
|
||||
|
||||
$sql = 'select * from ControlPresets where MonitorId = ?';
|
||||
$labels = array();
|
||||
foreach( dbFetchAll( $sql, NULL, array( $monitor->Id() ) ) as $row )
|
||||
{
|
||||
$labels[$row['Preset']] = $row['Label'];
|
||||
}
|
||||
$sql = 'SELECT * FROM ControlPresets WHERE MonitorId = ?';
|
||||
$labels = array();
|
||||
foreach( dbFetchAll( $sql, NULL, array( $monitor->Id() ) ) as $row ) {
|
||||
$labels[$row['Preset']] = $row['Label'];
|
||||
}
|
||||
|
||||
$presetBreak = (int)(($monitor->NumPresets()+1)/((int)(($monitor->NumPresets()-1)/MAX_PRESETS)+1));
|
||||
$presetBreak = (int)(($monitor->NumPresets()+1)/((int)(($monitor->NumPresets()-1)/MAX_PRESETS)+1));
|
||||
|
||||
ob_start();
|
||||
ob_start();
|
||||
?>
|
||||
<div class="presetControls">
|
||||
<!--<div><?php echo translate('Presets') ?></div>-->
|
||||
<div>
|
||||
<?php
|
||||
for ( $i = 1; $i <= $monitor->NumPresets(); $i++ )
|
||||
{
|
||||
?><input type="button" class="ptzNumBtn" title="<?php echo isset($labels[$i])?$labels[$i]:"" ?>" value="<?php echo $i ?>" onclick="controlCmd('<?php echo $cmds['PresetGoto'] ?><?php echo $i ?>');"/><?php
|
||||
if ( $i && (($i%$presetBreak) == 0) )
|
||||
{
|
||||
for ( $i = 1; $i <= $monitor->NumPresets(); $i++ ) {
|
||||
?>
|
||||
<input type="button" class="ptzNumBtn" title="<?php echo isset($labels[$i])?$labels[$i]:"" ?>" value="<?php echo $i ?>" onclick="controlCmd('<?php echo $cmds['PresetGoto'] ?><?php echo $i ?>');"/>
|
||||
<?php
|
||||
if ( $i && (($i%$presetBreak) == 0) ) {
|
||||
?><br/><?php
|
||||
}
|
||||
}
|
||||
} // end foreach preset
|
||||
?>
|
||||
</div>
|
||||
<div>
|
||||
<?php
|
||||
if ( $monitor->HasHomePreset() )
|
||||
{
|
||||
if ( $monitor->HasHomePreset() ) {
|
||||
?>
|
||||
<input type="button" class="ptzTextBtn" value="<?php echo translate('Home') ?>" onclick="controlCmd('<?php echo $cmds['PresetHome'] ?>');"/>
|
||||
<?php
|
||||
}
|
||||
if ( canEdit( 'Monitors') && $monitor->CanSetPresets() )
|
||||
{
|
||||
}
|
||||
if ( canEdit('Monitors') && $monitor->CanSetPresets() ) {
|
||||
?>
|
||||
<input type="button" class="ptzTextBtn" value="<?php echo translate('Set') ?>" onclick="createPopup( '?view=controlpreset&mid=<?php echo $monitor->Id() ?>', 'zmPreset', 'preset' );"/>
|
||||
<input type="button" class="ptzTextBtn" value="<?php echo translate('Set') ?>" onclick="createPopup('?view=controlpreset&mid=<?php echo $monitor->Id() ?>', 'zmPreset', 'preset');"/>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
return( ob_get_clean() );
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
function controlPower( $monitor, $cmds )
|
||||
{
|
||||
global $SLANG;
|
||||
function controlPower( $monitor, $cmds ) {
|
||||
global $SLANG;
|
||||
|
||||
ob_start();
|
||||
ob_start();
|
||||
?>
|
||||
<div class="powerControls">
|
||||
<div class="powerLabel"><?php echo translate('Control') ?></div>
|
||||
<div>
|
||||
<?php
|
||||
if ( $monitor->CanWake() )
|
||||
{
|
||||
if ( $monitor->CanWake() ) {
|
||||
?>
|
||||
<input type="button" class="ptzTextBtn" value="<?php echo translate('Wake') ?>" onclick="controlCmd('<?php echo $cmds['Wake'] ?>')"/>
|
||||
<?php
|
||||
}
|
||||
if ( $monitor->CanSleep() )
|
||||
{
|
||||
}
|
||||
if ( $monitor->CanSleep() ) {
|
||||
?>
|
||||
<input type="button" class="ptzTextBtn" value="<?php echo translate('Sleep') ?>" onclick="controlCmd('<?php echo $cmds['Sleep'] ?>')"/>
|
||||
<?php
|
||||
}
|
||||
if ( $monitor->CanReset() )
|
||||
{
|
||||
}
|
||||
if ( $monitor->CanReset() ) {
|
||||
?>
|
||||
<input type="button" class="ptzTextBtn" value="<?php echo translate('Reset') ?>" onclick="controlCmd('<?php echo $cmds['Reset'] ?>')"/>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
return( ob_get_clean() );
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
function ptzControls( $monitor )
|
||||
{
|
||||
$cmds = getControlCommands( $monitor );
|
||||
ob_start();
|
||||
function ptzControls( $monitor ) {
|
||||
$cmds = getControlCommands($monitor);
|
||||
ob_start();
|
||||
?>
|
||||
<div class="controlsPanel">
|
||||
<div class="controlsPanel">
|
||||
<?php
|
||||
if ( $monitor->CanFocus() )
|
||||
echo controlFocus( $monitor, $cmds );
|
||||
if ( $monitor->CanZoom() )
|
||||
echo controlZoom( $monitor, $cmds );
|
||||
if ( $monitor->CanIris() )
|
||||
echo controlIris( $monitor, $cmds );
|
||||
if ( $monitor->CanWhite() )
|
||||
echo controlWhite( $monitor, $cmds );
|
||||
if ( $monitor->CanMove() ) {
|
||||
if ( $monitor->CanFocus() )
|
||||
echo controlFocus($monitor, $cmds);
|
||||
if ( $monitor->CanZoom() )
|
||||
echo controlZoom($monitor, $cmds);
|
||||
if ( $monitor->CanIris() )
|
||||
echo controlIris($monitor, $cmds);
|
||||
if ( $monitor->CanWhite() )
|
||||
echo controlWhite($monitor, $cmds);
|
||||
if ( $monitor->CanMove() ) {
|
||||
?>
|
||||
<div class="pantiltPanel">
|
||||
<div class="pantiltPanel">
|
||||
<?php echo controlPanTilt($monitor, $cmds); ?>
|
||||
</div>
|
||||
<?php
|
||||
echo controlPanTilt( $monitor, $cmds );
|
||||
}
|
||||
if ( $monitor->CanWake() || $monitor->CanSleep() || $monitor->CanReset() )
|
||||
echo controlPower($monitor, $cmds);
|
||||
if ( $monitor->HasPresets() )
|
||||
echo controlPresets($monitor, $cmds);
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
if ( $monitor->CanWake() || $monitor->CanSleep() || $monitor->CanReset() )
|
||||
echo controlPower( $monitor, $cmds );
|
||||
if ( $monitor->HasPresets() )
|
||||
echo controlPresets( $monitor, $cmds );
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
return( ob_get_clean() );
|
||||
return ob_get_clean();
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -732,11 +732,6 @@ function loadintoIframe(iframeid, url){
|
|||
return( ob_get_clean() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function exportFileList( $eid, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc ) {
|
||||
|
||||
if ( (!canView('Events')) or ! $eid ) {
|
||||
|
@ -816,7 +811,7 @@ function exportFileList( $eid, $exportDetail, $exportFrames, $exportImages, $exp
|
|||
}
|
||||
$files = array();
|
||||
}
|
||||
return( array_values( $exportFileList ) );
|
||||
return array_values($exportFileList);
|
||||
}
|
||||
|
||||
function exportEvents( $eids, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc, $exportFormat, $exportStructure = false ) {
|
||||
|
@ -900,5 +895,5 @@ function exportEvents( $eids, $exportDetail, $exportFrames, $exportImages, $expo
|
|||
unlink($monitorPath.'/'.$html_eventMaster);
|
||||
}
|
||||
|
||||
return( '?view=archive%26type='.$exportFormat );
|
||||
return '?view=archive%26type='.$exportFormat;
|
||||
}
|
||||
|
|
|
@ -373,18 +373,13 @@ function xhtmlFooter() {
|
|||
global $view;
|
||||
global $skin;
|
||||
global $running;
|
||||
if ( canEdit('System') ) {
|
||||
include("skins/$skin/views/state.php");
|
||||
if ( canEdit('System') ) {
|
||||
include("skins/$skin/views/state.php");
|
||||
}
|
||||
?>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
<script type="text/javascript">
|
||||
$j('.chosen').chosen();
|
||||
</script>
|
||||
</body>
|
||||
<script type="text/javascript">$j('.chosen').chosen();</script>
|
||||
</html>
|
||||
<?php
|
||||
} // end xhtmlFooter
|
||||
|
||||
?>
|
||||
|
|
|
@ -56,7 +56,7 @@ var popupSizes = {
|
|||
'onvifprobe': { 'width': 700, 'height': 550 },
|
||||
'optionhelp': { 'width': 400, 'height': 320 },
|
||||
'options': { 'width': 1000, 'height': 660 },
|
||||
'preset': { 'width': 300, 'height': 120 },
|
||||
'preset': { 'width': 300, 'height': 220 },
|
||||
'server': { 'width': 600, 'height': 405 },
|
||||
'settings': { 'width': 220, 'height': 235 },
|
||||
'state': { 'width': 400, 'height': 170 },
|
||||
|
|
|
@ -182,7 +182,7 @@ function refreshParentWindow() {
|
|||
}
|
||||
}
|
||||
|
||||
if ( currentView != 'none' ) {
|
||||
if ( currentView != 'none' && currentView != 'login' ) {
|
||||
$j.ajaxSetup ({timeout: AJAX_TIMEOUT }); //sets timeout for all getJSON.
|
||||
|
||||
$j(document).ready(function() {
|
||||
|
@ -192,7 +192,15 @@ if ( currentView != 'none' ) {
|
|||
});
|
||||
|
||||
function getNavBar() {
|
||||
$j.getJSON(thisUrl + '?view=request&request=status&entity=navBar', setNavBar);
|
||||
$j.getJSON(thisUrl + '?view=request&request=status&entity=navBar')
|
||||
.done(setNavBar)
|
||||
.fail(function( jqxhr, textStatus, error ) {
|
||||
var err = textStatus + ", " + error;
|
||||
console.log( "Request Failed: " + err );
|
||||
// The idea is that this should only fail due to auth, so reload the page
|
||||
// which should go to login if it can't stay logged in.
|
||||
window.location.href = thisUrl;
|
||||
});
|
||||
}
|
||||
|
||||
function setNavBar(data) {
|
||||
|
|
|
@ -34,6 +34,8 @@ var skinPath = "<?php echo ZM_SKIN_PATH ?>";
|
|||
|
||||
var canEditSystem = <?php echo canEdit('System' )?'true':'false' ?>;
|
||||
var canViewSystem = <?php echo canView('System' )?'true':'false' ?>;
|
||||
var canEditEvents = <?php echo canEdit('Events' )?'true':'false' ?>;
|
||||
var canViewEvents = <?php echo canView('Events' )?'true':'false' ?>;
|
||||
|
||||
var canEditGroups = <?php echo canEdit('Groups' )?'true':'false' ?>;
|
||||
|
||||
|
|
|
@ -218,7 +218,9 @@ $html .= htmlSelect( 'Status[]', $status_options,
|
|||
$regexp = '/'.preg_quote($regexp,'/').'/i';
|
||||
}
|
||||
if ( !preg_match($regexp, $Monitor->Source()) ) {
|
||||
continue;
|
||||
if ( !preg_match($regexp, $Monitor->Path()) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ ob_start();
|
|||
<?php } ?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="consoleTableBody">
|
||||
<tbody id="consoleTableBody">
|
||||
<?php
|
||||
$table_head = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
|
|
@ -18,30 +18,26 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canEdit( 'Monitors' ) )
|
||||
{
|
||||
$view = "error";
|
||||
return;
|
||||
if ( !canEdit('Monitors') ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
$monitor = dbFetchOne( 'SELECT C.*,M.* FROM Monitors AS M INNER JOIN Controls AS C ON (M.ControlId = C.Id ) WHERE M.Id = ?', NULL, array( $_REQUEST['mid']) );
|
||||
$monitor = dbFetchOne('SELECT C.*,M.* FROM Monitors AS M INNER JOIN Controls AS C ON (M.ControlId = C.Id ) WHERE M.Id = ?', NULL, array( $_REQUEST['mid']) );
|
||||
|
||||
$labels = array();
|
||||
foreach( dbFetchAll( 'SELECT * FROM ControlPresets WHERE MonitorId = ?', NULL, array( $monitor['Id'] ) ) as $row ) {
|
||||
$labels[$row['Preset']] = $row['Label'];
|
||||
$labels[$row['Preset']] = $row['Label'];
|
||||
}
|
||||
|
||||
$presets = array();
|
||||
for ( $i = 1; $i <= $monitor['NumPresets']; $i++ )
|
||||
{
|
||||
$presets[$i] = translate('Preset')." ".$i;
|
||||
if ( !empty($labels[$i]) )
|
||||
{
|
||||
$presets[$i] .= " (".validHtmlStr($labels[$i]).")";
|
||||
}
|
||||
for ( $i = 1; $i <= $monitor['NumPresets']; $i++ ) {
|
||||
$presets[$i] = translate('Preset').' '.$i;
|
||||
if ( !empty($labels[$i]) ) {
|
||||
$presets[$i] .= ' ('.validHtmlStr($labels[$i]).')';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$focusWindow = true;
|
||||
|
||||
xhtmlHeaders(__FILE__, translate('SetPreset') );
|
||||
|
@ -58,10 +54,14 @@ xhtmlHeaders(__FILE__, translate('SetPreset') );
|
|||
<input type="hidden" name="action" value="control"/>
|
||||
<input type="hidden" name="control" value="presetSet"/>
|
||||
<input type="hidden" name="showControls" value="1"/>
|
||||
<p><?php echo buildSelect( "preset", $presets, "updateLabel()" ) ?></p>
|
||||
<p><label for="newLabel"><?php echo translate('NewLabel') ?></label><input type="text" name="newLabel" id="newLabel" value="" size="16"/></p>
|
||||
<p><?php echo buildSelect('preset', $presets, 'updateLabel()' ) ?></p>
|
||||
<p>
|
||||
<label for="newLabel"><?php echo translate('NewLabel') ?></label>
|
||||
<input type="text" name="newLabel" id="newLabel" value="" size="16"/>
|
||||
</p>
|
||||
<div id="contentButtons">
|
||||
<input type="submit" value="<?php echo translate('Save') ?>"/><input type="button" value="<?php echo translate('Cancel') ?>" onclick="closeWindow()"/>
|
||||
<input type="submit" value="<?php echo translate('Save') ?>"/>
|
||||
<input type="button" value="<?php echo translate('Cancel') ?>" onclick="closeWindow()"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -66,7 +66,10 @@ if ( !empty($_REQUEST['eid']) ) {
|
|||
$Event = new Event( $_REQUEST['eid'] );
|
||||
echo 'Downloading event ' . $_REQUEST['eid'] . ' Resulting file should be approximately ' . human_filesize( $Event->DiskSpace() );
|
||||
} else if ( !empty($_REQUEST['eids']) ) {
|
||||
$total_size = 0;
|
||||
foreach ( $_REQUEST['eids'] as $eid ) {
|
||||
$Event = new Event($eid);
|
||||
$total_size += $Event->DiskSpace();
|
||||
?>
|
||||
<input type="hidden" name="eids[]" value="<?php echo validInt($eid) ?>"/>
|
||||
<?php
|
||||
|
@ -74,7 +77,7 @@ if ( !empty($_REQUEST['eid']) ) {
|
|||
unset( $eid );
|
||||
echo "Downloading " . count($_REQUEST['eids']) . ' events. Resulting file should be approximately ' . human_filesize($total_size);
|
||||
} else {
|
||||
echo '<div class="warning">There are no events found. Resulting download will be empty.</div>';
|
||||
echo '<div class="warning">There are no events found. Resulting download will be empty.</div>';
|
||||
}
|
||||
?>
|
||||
<table id="contentTable" class="minor" cellspacing="0">
|
||||
|
|
|
@ -142,7 +142,6 @@ if ( $pages > 1 ) {
|
|||
$count = 0;
|
||||
$disk_space_total = 0;
|
||||
|
||||
Logger::Debug("EventSql: $eventsSql");
|
||||
$results = dbQuery($eventsSql);
|
||||
while ( $event_row = dbFetchNext($results) ) {
|
||||
$event = new Event($event_row);
|
||||
|
@ -173,7 +172,7 @@ while ( $event_row = dbFetchNext($results) ) {
|
|||
}
|
||||
if ( ZM_WEB_EVENT_DISK_SPACE ) {
|
||||
?>
|
||||
<th class="colDiskSpace"><a href="<?php echo sortHeader( 'DiskSpace' ) ?>"><?php echo translate('DiskSpace') ?><?php echo sortTag( 'DiskSpace' ) ?></a></th>
|
||||
<th class="colDiskSpace"><a href="<?php echo sortHeader('DiskSpace') ?>"><?php echo translate('DiskSpace') ?><?php echo sortTag('DiskSpace') ?></a></th>
|
||||
<?php
|
||||
}
|
||||
if ( ZM_WEB_LIST_THUMBS ) {
|
||||
|
@ -182,7 +181,7 @@ while ( $event_row = dbFetchNext($results) ) {
|
|||
<?php
|
||||
}
|
||||
?>
|
||||
<th class="colMark"><input type="checkbox" name="toggleCheck" value="1" onclick="toggleCheckbox( this, 'markEids' );"<?php if ( !canEdit( 'Events' ) ) { ?> disabled="disabled"<?php } ?>/></th>
|
||||
<th class="colMark"><input type="checkbox" name="toggleCheck" value="1" onclick="toggleCheckbox(this, 'markEids');"/></th>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
@ -226,7 +225,7 @@ while ( $event_row = dbFetchNext($results) ) {
|
|||
echo '</td>';
|
||||
} // end if ZM_WEB_LIST_THUMBS
|
||||
?>
|
||||
<td class="colMark"><input type="checkbox" name="markEids[]" value="<?php echo $event->Id() ?>" onclick="configureButton( this, 'markEids' );"<?php if ( !canEdit( 'Events' ) ) { ?> disabled="disabled"<?php } ?>/></td>
|
||||
<td class="colMark"><input type="checkbox" name="markEids[]" value="<?php echo $event->Id() ?>" onclick="configureButton(this, 'markEids');"/></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canView( 'Events' ) ) {
|
||||
if ( !canView('Events') ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
@ -53,16 +53,12 @@ xhtmlHeaders(__FILE__, translate('Export') );
|
|||
<div id="content">
|
||||
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<?php
|
||||
if ( !empty($_REQUEST['eid']) )
|
||||
{
|
||||
if ( !empty($_REQUEST['eid']) ) {
|
||||
?>
|
||||
<input type="hidden" name="id" value="<?php echo validInt($_REQUEST['eid']) ?>"/>
|
||||
<?php
|
||||
}
|
||||
elseif ( !empty($_REQUEST['eids']) )
|
||||
{
|
||||
foreach ( $_REQUEST['eids'] as $eid )
|
||||
{
|
||||
} elseif ( !empty($_REQUEST['eids']) ) {
|
||||
foreach ( $_REQUEST['eids'] as $eid ) {
|
||||
?>
|
||||
<input type="hidden" name="eids[]" value="<?php echo validInt($eid) ?>"/>
|
||||
<?php
|
||||
|
@ -70,7 +66,7 @@ elseif ( !empty($_REQUEST['eids']) )
|
|||
unset( $eid );
|
||||
}
|
||||
?>
|
||||
<table id="contentTable" class="minor" cellspacing="0">
|
||||
<table id="contentTable" class="minor">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('ExportDetails') ?></th>
|
||||
|
@ -101,7 +97,7 @@ elseif ( !empty($_REQUEST['eids']) )
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button id="exportButton" name="exportButton" value="Export" onclick="exportEvent(this.form);" disabled="disabled"><?php echo translate('Export') ?></button>
|
||||
<button type="button" id="exportButton" name="exportButton" value="Export" onclick="exportEvent(this.form);" disabled="disabled"><?php echo translate('Export') ?></button>
|
||||
</form>
|
||||
</div>
|
||||
<?php
|
||||
|
|
|
@ -346,17 +346,17 @@ echo htmlSelect( 'filter[Query][sort_asc]', $sort_dirns, $filter->sort_asc() );
|
|||
<div id="actionsTable" class="filterTable">
|
||||
<p>
|
||||
<label><?php echo translate('FilterArchiveEvents') ?></label>
|
||||
<input type="checkbox" name="filter[AutoArchive]" value="1"<?php if ( !empty($filter->AutoArchive()) ) { ?> checked="checked"<?php } ?> onclick="updateButtons( this )"/>
|
||||
<input type="checkbox" name="filter[AutoArchive]" value="1"<?php if ( $filter->AutoArchive() ) { ?> checked="checked"<?php } ?> onclick="updateButtons( this )"/>
|
||||
</p>
|
||||
<p><label><?php echo translate('FilterUpdateDiskSpace') ?></label>
|
||||
<input type="checkbox" name="filter[UpdateDiskSpace]" value="1"<?php echo empty($filter->UpdateDiskSpace()) ? '' : ' checked="checked"' ?> onclick="updateButtons(this);"/>
|
||||
<input type="checkbox" name="filter[UpdateDiskSpace]" value="1"<?php echo !$filter->UpdateDiskSpace() ? '' : ' checked="checked"' ?> onclick="updateButtons(this);"/>
|
||||
</p>
|
||||
<?php
|
||||
if ( ZM_OPT_FFMPEG ) {
|
||||
?>
|
||||
<p>
|
||||
<label><?php echo translate('FilterVideoEvents') ?></label>
|
||||
<input type="checkbox" name="filter[AutoVideo]" value="1"<?php if ( !empty($filter->AutoVideo()) ) { ?> checked="checked"<?php } ?> onclick="updateButtons( this )"/>
|
||||
<input type="checkbox" name="filter[AutoVideo]" value="1"<?php if ( $filter->AutoVideo() ) { ?> checked="checked"<?php } ?> onclick="updateButtons( this )"/>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
@ -364,7 +364,7 @@ if ( ZM_OPT_UPLOAD ) {
|
|||
?>
|
||||
<p>
|
||||
<label><?php echo translate('FilterUploadEvents') ?></label>
|
||||
<input type="checkbox" name="filter[AutoUpload]" value="1"<?php if ( !empty($filter->AutoUpload()) ) { ?> checked="checked"<?php } ?> onclick="updateButtons( this )"/>
|
||||
<input type="checkbox" name="filter[AutoUpload]" value="1"<?php if ( $filter->AutoUpload() ) { ?> checked="checked"<?php } ?> onclick="updateButtons( this )"/>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
@ -372,7 +372,7 @@ if ( ZM_OPT_EMAIL ) {
|
|||
?>
|
||||
<p>
|
||||
<label><?php echo translate('FilterEmailEvents') ?></label>
|
||||
<input type="checkbox" name="filter[AutoEmail]" value="1"<?php if ( !empty($filter->AutoEmail()) ) { ?> checked="checked"<?php } ?> onclick="updateButtons( this )"/>
|
||||
<input type="checkbox" name="filter[AutoEmail]" value="1"<?php if ( $filter->AutoEmail() ) { ?> checked="checked"<?php } ?> onclick="updateButtons( this )"/>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
@ -380,7 +380,7 @@ if ( ZM_OPT_MESSAGE ) {
|
|||
?>
|
||||
<p>
|
||||
<label><?php echo translate('FilterMessageEvents') ?></label>
|
||||
<input type="checkbox" name="filter[AutoMessage]" value="1"<?php if ( !empty($filter->AutoMessage()) ) { ?> checked="checked"<?php } ?> onclick="updateButtons( this )"/>
|
||||
<input type="checkbox" name="filter[AutoMessage]" value="1"<?php if ( $filter->AutoMessage() ) { ?> checked="checked"<?php } ?> onclick="updateButtons( this )"/>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
@ -388,24 +388,24 @@ if ( ZM_OPT_MESSAGE ) {
|
|||
<p>
|
||||
<label><?php echo translate('FilterExecuteEvents') ?></label>
|
||||
|
||||
<input type="checkbox" name="filter[AutoExecute]" value="1"<?php if ( !empty($filter->AutoExecute()) ) { ?> checked="checked"<?php } ?>/>
|
||||
<input type="checkbox" name="filter[AutoExecute]" value="1"<?php if ( $filter->AutoExecute() ) { ?> checked="checked"<?php } ?>/>
|
||||
<input type="text" name="filter[AutoExecuteCmd]" value="<?php echo (null !==$filter->AutoExecuteCmd())?$filter->AutoExecuteCmd():'' ?>" maxlength="255" onchange="updateButtons( this )"/>
|
||||
</p>
|
||||
<p>
|
||||
<label><?php echo translate('FilterDeleteEvents') ?></label>
|
||||
<input type="checkbox" name="filter[AutoDelete]" value="1"<?php if ( !empty($filter->AutoDelete()) ) { ?> checked="checked"<?php } ?> onclick="updateButtons(this)"/>
|
||||
<input type="checkbox" name="filter[AutoDelete]" value="1"<?php if ( $filter->AutoDelete() ) { ?> checked="checked"<?php } ?> onclick="updateButtons(this)"/>
|
||||
</p>
|
||||
<p><label><?php echo translate('FilterMoveEvents') ?></label>
|
||||
<input type="checkbox" name="filter[AutoMove]" value="1"<?php if ( !empty($filter->AutoMove()) ) { ?> checked="checked"<?php } ?> onclick="updateButtons(this);if(this.checked){$j(this.form.elements['filter[AutoMoveTo]']).css('display','inline');}else{this.form.elements['filter[AutoMoveTo]'].hide();};"/>
|
||||
<input type="checkbox" name="filter[AutoMove]" value="1"<?php if ( $filter->AutoMove() ) { ?> checked="checked"<?php } ?> onclick="updateButtons(this);if(this.checked){$j(this.form.elements['filter[AutoMoveTo]']).css('display','inline');}else{this.form.elements['filter[AutoMoveTo]'].hide();};"/>
|
||||
<?php echo htmlSelect( "filter[AutoMoveTo]", $storageareas, $filter->AutoMoveTo(), $filter->AutoMove() ? null : array('style'=>'display:none;' ) ); ?>
|
||||
</p>
|
||||
<p>
|
||||
<label for="background"><?php echo translate('BackgroundFilter') ?></label>
|
||||
<input type="checkbox" id="filter[Background]" name="filter[Background]" value="1"<?php if ( !empty($filter->Background()) ) { ?> checked="checked"<?php } ?> onclick="updateButtons(this);"/>
|
||||
<input type="checkbox" id="filter[Background]" name="filter[Background]" value="1"<?php if ( $filter->Background() ) { ?> checked="checked"<?php } ?> onclick="updateButtons(this);"/>
|
||||
</p>
|
||||
<p>
|
||||
<label for="Concurrent"><?php echo translate('ConcurrentFilter') ?></label>
|
||||
<input type="checkbox" id="filter[Concurrent]" name="filter[Concurrent]" value="1"<?php if ( !empty($filter->Concurrent()) ) { ?> checked="checked"<?php } ?> onclick="updateButtons(this);"/>
|
||||
<input type="checkbox" id="filter[Concurrent]" name="filter[Concurrent]" value="1"<?php if ( $filter->Concurrent() ) { ?> checked="checked"<?php } ?> onclick="updateButtons(this);"/>
|
||||
</p>
|
||||
</div>
|
||||
<hr/>
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
function updateLabel() {
|
||||
var presetIndex = $('contentForm').preset.getValue();
|
||||
var form = $('contentForm');
|
||||
var preset_ddm = form.elements['preset'];
|
||||
|
||||
var presetIndex = preset_ddm[preset_ddm.selectedIndex].value;
|
||||
if ( labels[presetIndex] ) {
|
||||
$('contentForm').newLabel.value = labels[presetIndex];
|
||||
form.newLabel.value = labels[presetIndex];
|
||||
} else {
|
||||
$('contentForm').newLabel.value = "";
|
||||
form.newLabel.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
window.addEvent( 'domready', updateLabel );
|
||||
window.addEvent('domready', updateLabel);
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
var labels = new Array();
|
||||
<?php
|
||||
foreach ( $labels as $index=>$label )
|
||||
{
|
||||
foreach ( $labels as $index=>$label ) {
|
||||
?>
|
||||
labels[<?php echo validInt($index) ?>] = "<?php echo validJsStr($label) ?>";
|
||||
labels[<?php echo validInt($index) ?>] = '<?php echo validJsStr($label) ?>';
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
if ( isset($_REQUEST['eids']) ) {
|
||||
$eidParms = array();
|
||||
foreach ( $_REQUEST['eids'] as $eid )
|
||||
$eidParms[] = "eids[]=".validInt($eid);
|
||||
$eidParms[] = 'eids[]='.validInt($eid);
|
||||
?>
|
||||
var eidParm = '<?php echo join( '&', $eidParms ) ?>';
|
||||
var eidParm = '<?php echo join('&', $eidParms) ?>';
|
||||
<?php
|
||||
} else if (isset($_REQUEST['eid'])) {
|
||||
?>
|
||||
|
|
|
@ -11,13 +11,13 @@ function toggleCheckbox( element, name ) {
|
|||
for (var i = 0; i < form.elements.length; i++)
|
||||
if (form.elements[i].name.indexOf(name) == 0)
|
||||
form.elements[i].checked = checked;
|
||||
form.viewBtn.disabled = !checked;
|
||||
form.editBtn.disabled = !checked;
|
||||
form.viewBtn.disabled = !(canViewEvents && checked);
|
||||
form.editBtn.disabled = !(canEditEvents && checked);
|
||||
form.archiveBtn.disabled = unarchivedEvents?!checked:true;
|
||||
form.unarchiveBtn.disabled = archivedEvents?!checked:true;
|
||||
form.downloadBtn.disabled = !checked;
|
||||
form.exportBtn.disabled = !checked;
|
||||
form.deleteBtn.disabled = !checked;
|
||||
form.unarchiveBtn.disabled = !(canEditEvents && archivedEvents && checked);
|
||||
form.downloadBtn.disabled = !(canViewEvents && checked);
|
||||
form.exportBtn.disabled = !(canViewEvents && checked);
|
||||
form.deleteBtn.disabled = !(canEditEvents && checked);
|
||||
}
|
||||
|
||||
function configureButton( element, name ) {
|
||||
|
@ -35,16 +35,20 @@ function configureButton( element, name ) {
|
|||
}
|
||||
if ( !element.checked )
|
||||
form.toggleCheck.checked = false;
|
||||
form.viewBtn.disabled = !checked;
|
||||
form.editBtn.disabled = !checked;
|
||||
form.viewBtn.disabled = !(canViewEvents && checked);
|
||||
form.editBtn.disabled = !(canEditEvents && checked);
|
||||
form.archiveBtn.disabled = (!checked)||(!unarchivedEvents);
|
||||
form.unarchiveBtn.disabled = (!checked)||(!archivedEvents);
|
||||
form.downloadBtn.disabled = !checked;
|
||||
form.exportBtn.disabled = !checked;
|
||||
form.deleteBtn.disabled = !checked;
|
||||
form.unarchiveBtn.disabled = !(canEditEvents && checked && archivedEvents);
|
||||
form.downloadBtn.disabled = !(canViewEvents && checked);
|
||||
form.exportBtn.disabled = !(canViewEvents && checked);
|
||||
form.deleteBtn.disabled = !(canEditEvents && checked);
|
||||
}
|
||||
|
||||
function deleteEvents( element, name ) {
|
||||
if ( ! canEditEvents ) {
|
||||
alert("You do not have permission to delete events.");
|
||||
return;
|
||||
}
|
||||
var form = element.form;
|
||||
var count = 0;
|
||||
for (var i = 0; i < form.elements.length; i++) {
|
||||
|
@ -64,6 +68,10 @@ function deleteEvents( element, name ) {
|
|||
}
|
||||
|
||||
function editEvents( element, name ) {
|
||||
if ( ! canEditEvents ) {
|
||||
alert("You do not have permission to delete events.");
|
||||
return;
|
||||
}
|
||||
var form = element.form;
|
||||
var eids = new Array();
|
||||
for (var i = 0; i < form.elements.length; i++) {
|
||||
|
@ -125,6 +133,10 @@ function archiveEvents( element, name ) {
|
|||
}
|
||||
|
||||
function unarchiveEvents(element, name) {
|
||||
if ( ! canEditEvents ) {
|
||||
alert("You do not have permission to delete events.");
|
||||
return;
|
||||
}
|
||||
var form = element.form;
|
||||
form.elements['action'].value = 'unarchive';
|
||||
form.submit();
|
||||
|
|
|
@ -34,7 +34,7 @@ function buildFetchParms( parms ) {
|
|||
fetchParms += '&filter['+key+']='+value;
|
||||
}
|
||||
);
|
||||
return( fetchParms );
|
||||
return fetchParms;
|
||||
}
|
||||
|
||||
function fetchNextLogs() {
|
||||
|
@ -229,24 +229,25 @@ function updateFilterSelectors() {
|
|||
if ( key == 'Level' ) {
|
||||
Object.each(values,
|
||||
function( value, label ) {
|
||||
selector.options[selector.options.length] = new Option( value, label );
|
||||
selector.options[selector.options.length] = new Option(value, label);
|
||||
}
|
||||
);
|
||||
} else if ( key == 'ServerId' ) {
|
||||
Object.each(values,
|
||||
function( value, label ) {
|
||||
selector.options[selector.options.length] = new Option( value, label );
|
||||
selector.options[selector.options.length] = new Option(value, label);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
values.each(
|
||||
function( value ) {
|
||||
selector.options[selector.options.length] = new Option( value );
|
||||
Object.each(values,
|
||||
function( value, label ) {
|
||||
selector.options[selector.options.length] = new Option(value, label);
|
||||
}
|
||||
);
|
||||
}
|
||||
if ( filter[key] )
|
||||
selector.set('value', filter[key]);
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -257,11 +258,11 @@ function initPage() {
|
|||
logCodes[''+i] = 'DB'+i;
|
||||
logTable = new HtmlTable( $('logTable'),
|
||||
{
|
||||
zebra: true,
|
||||
sortable: true,
|
||||
sortReverse: true
|
||||
}
|
||||
);
|
||||
zebra: true,
|
||||
sortable: true,
|
||||
sortReverse: true
|
||||
}
|
||||
);
|
||||
logTable.addEvent( 'sort', function( tbody, index ) {
|
||||
var header = tbody.getParent( 'table' ).getElement( 'thead' );
|
||||
var columns = header.getElement( 'tr' ).getElements( 'th' );
|
||||
|
|
|
@ -18,10 +18,9 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canView( 'System' ) )
|
||||
{
|
||||
$view = "error";
|
||||
return;
|
||||
if ( !canView('System') ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
$focusWindow = true;
|
||||
|
@ -31,92 +30,90 @@ xhtmlHeaders(__FILE__, translate('SystemLog') );
|
|||
<body>
|
||||
<div id="page">
|
||||
<div id="header">
|
||||
<table class="table">
|
||||
<tr class="row">
|
||||
<td class="col text-center">
|
||||
<div id="logSummary">
|
||||
<?php echo translate('State') ?>: <span id="logState"></span>/
|
||||
<?php echo translate('Total') ?>: <span id="totalLogs"></span>/
|
||||
<?php echo translate('Available') ?>: <span id="availLogs"></span>/
|
||||
<?php echo translate('Displaying') ?>: <span id="displayLogs"></span>/
|
||||
<?php echo translate('Updated') ?>: <span id="lastUpdate"></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="row">
|
||||
<table class="table">
|
||||
<tr class="row">
|
||||
<td class="col text-center">
|
||||
<div id="logSummary">
|
||||
<?php echo translate('State') ?>: <span id="logState"></span>/
|
||||
<?php echo translate('Total') ?>: <span id="totalLogs"></span>/
|
||||
<?php echo translate('Available') ?>: <span id="availLogs"></span>/
|
||||
<?php echo translate('Displaying') ?>: <span id="displayLogs"></span>/
|
||||
<?php echo translate('Updated') ?>: <span id="lastUpdate"></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="row">
|
||||
<td class="col text-center">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-sm" onclick="expandLog()"> <?php echo translate('More') ?></button>
|
||||
<button type="button" class="btn btn-sm" onclick="clearLog()"> <?php echo translate('Clear') ?></button>
|
||||
<button type="button" class="btn btn-sm" onclick="refreshLog()"> <?php echo translate('Refresh') ?></button>
|
||||
<button type="button" class="btn btn-sm" onclick="exportLog()"> <?php echo translate('Export') ?></button>
|
||||
<button type="button" class="btn btn-sm" onclick="closeWindow()"> <?php echo translate('Close') ?></button>
|
||||
</div> <!--btn-->
|
||||
</td>
|
||||
</tr>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-sm" onclick="expandLog()"> <?php echo translate('More') ?></button>
|
||||
<button type="button" class="btn btn-sm" onclick="clearLog()"> <?php echo translate('Clear') ?></button>
|
||||
<button type="button" class="btn btn-sm" onclick="refreshLog()"> <?php echo translate('Refresh') ?></button>
|
||||
<button type="button" class="btn btn-sm" onclick="exportLog()"> <?php echo translate('Export') ?></button>
|
||||
<button type="button" class="btn btn-sm" onclick="closeWindow()"> <?php echo translate('Close') ?></button>
|
||||
</div> <!--btn-->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div> <!--header-->
|
||||
<div id="content">
|
||||
|
||||
<div id="filters">
|
||||
|
||||
<table cellpadding="5" class="table-condensed">
|
||||
<tr class="row">
|
||||
<td class="col">
|
||||
<?php echo translate('Component') ?>
|
||||
<select class="form-control chosen" id="filter[Component]" onchange="filterLog(this)"><option value="">-----</option></select>
|
||||
</td>
|
||||
<td class="col">
|
||||
<?php echo translate('Server') ?>
|
||||
<select class="form-control chosen" id="filter[ServerId]" onchange="filterLog(this)"><option value="">-----</option></select>
|
||||
</td>
|
||||
<td class="col">
|
||||
<?php echo translate('Pid') ?>
|
||||
<select class="form-control chosen" id="filter[Pid]" onchange="filterLog(this)"><option value="">-----</option></select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="row">
|
||||
<td class="col">
|
||||
<?php echo translate('Level') ?>
|
||||
<select class="form-control chosen" id="filter[Level]" onchange="filterLog(this)"><option value="">---</option></select>
|
||||
</td>
|
||||
<td class="col">
|
||||
<?php echo translate('File') ?>
|
||||
<select class="form-control chosen" id="filter[File]" onchange="filterLog(this)"><option value="">------</option></select>
|
||||
</td>
|
||||
<td class="col">
|
||||
<?php echo translate('Line') ?>
|
||||
<select class="form-control chosen" id="filter[Line]" onchange="filterLog(this)"><option value="">----</option></select>
|
||||
</td>
|
||||
</tr>
|
||||
</div> <!--header-->
|
||||
<div id="content">
|
||||
<div id="filters">
|
||||
|
||||
</table>
|
||||
<input type="reset" value="<?php echo translate('Reset') ?>" onclick="resetLog()"/>
|
||||
</div>
|
||||
<form name="logForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<table id="logTable" class="major" cellspacing="0">
|
||||
<thead class="thead-highlight">
|
||||
<tr>
|
||||
<th><?php echo translate('DateTime') ?></th>
|
||||
<th class="table-th-nosort"><?php echo translate('Component') ?></th>
|
||||
<th class="table-th-nosort"><?php echo translate('Server') ?></th>
|
||||
<th class="table-th-nosort"><?php echo translate('Pid') ?></th>
|
||||
<th class="table-th-nosort"><?php echo translate('Level') ?></th>
|
||||
<th class="table-th-nosort"><?php echo translate('Message') ?></th>
|
||||
<th class="table-th-nosort"><?php echo translate('File') ?></th>
|
||||
<th class="table-th-nosort"><?php echo translate('Line') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="contentButtons">
|
||||
</div>
|
||||
</form>
|
||||
<table class="table-condensed">
|
||||
<tr class="row">
|
||||
<td class="col">
|
||||
<?php echo translate('Component') ?>
|
||||
<select class="form-control chosen" id="filter[Component]" onchange="filterLog(this)"><option value="">-----</option></select>
|
||||
</td>
|
||||
<td class="col">
|
||||
<?php echo translate('Server') ?>
|
||||
<select class="form-control chosen" id="filter[ServerId]" onchange="filterLog(this)"><option value="">-----</option></select>
|
||||
</td>
|
||||
<td class="col">
|
||||
<?php echo translate('Pid') ?>
|
||||
<select class="form-control chosen" id="filter[Pid]" onchange="filterLog(this)"><option value="">-----</option></select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="row">
|
||||
<td class="col">
|
||||
<?php echo translate('Level') ?>
|
||||
<select class="form-control chosen" id="filter[Level]" onchange="filterLog(this)"><option value="">---</option></select>
|
||||
</td>
|
||||
<td class="col">
|
||||
<?php echo translate('File') ?>
|
||||
<select class="form-control chosen" id="filter[File]" onchange="filterLog(this)"><option value="">------</option></select>
|
||||
</td>
|
||||
<td class="col">
|
||||
<?php echo translate('Line') ?>
|
||||
<select class="form-control chosen" id="filter[Line]" onchange="filterLog(this)"><option value="">----</option></select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="reset" value="<?php echo translate('Reset') ?>" onclick="resetLog()"/>
|
||||
</div>
|
||||
<form name="logForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<table id="logTable" class="major">
|
||||
<thead class="thead-highlight">
|
||||
<tr>
|
||||
<th><?php echo translate('DateTime') ?></th>
|
||||
<th class="table-th-nosort"><?php echo translate('Component') ?></th>
|
||||
<th class="table-th-nosort"><?php echo translate('Server') ?></th>
|
||||
<th class="table-th-nosort"><?php echo translate('Pid') ?></th>
|
||||
<th class="table-th-nosort"><?php echo translate('Level') ?></th>
|
||||
<th class="table-th-nosort"><?php echo translate('Message') ?></th>
|
||||
<th class="table-th-nosort"><?php echo translate('File') ?></th>
|
||||
<th class="table-th-nosort"><?php echo translate('Line') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="contentButtons">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="exportLog" class="overlay">
|
||||
<div class="overlayHeader">
|
||||
<div class="overlayTitle"><?php echo translate('ExportLog') ?></div>
|
||||
|
|
|
@ -452,11 +452,6 @@ $savejpegopts = array(
|
|||
'Frames + Analysis images (if available)' => 3,
|
||||
);
|
||||
|
||||
$videowriteropts = array(
|
||||
'Disabled' => 0,
|
||||
'X264 Encode' => 1,
|
||||
'H264 Camera Passthrough' => 2
|
||||
);
|
||||
|
||||
xhtmlHeaders(__FILE__, translate('Monitor')." - ".validHtmlStr($monitor->Name()) );
|
||||
?>
|
||||
|
@ -922,7 +917,17 @@ if ( $monitor->Type() == 'Local' ) {
|
|||
case 'storage' :
|
||||
?>
|
||||
<tr><td><?php echo translate('SaveJPEGs') ?></td><td><select name="newMonitor[SaveJPEGs]"><?php foreach ( $savejpegopts as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->SaveJPEGs() ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||
<tr><td><?php echo translate('VideoWriter') ?></td><td><select name="newMonitor[VideoWriter]"><?php foreach ( $videowriteropts as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->VideoWriter() ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||
<tr><td><?php echo translate('VideoWriter') ?></td><td>
|
||||
<?php
|
||||
$videowriteropts = array(
|
||||
0 => 'Disabled',
|
||||
1 => 'X264 Encode',
|
||||
);
|
||||
if ($monitor->Type() == 'Ffmpeg' )
|
||||
$videowriteropts[2]='H264 Camera Passthrough';
|
||||
echo htmlselect( 'newMonitor[VideoWriter]', $videowriteropts, $monitor->VideoWriter() );
|
||||
?>
|
||||
</td></tr>
|
||||
<tr><td><?php echo translate('OptionalEncoderParam') ?></td><td><textarea name="newMonitor[EncoderParameters]" rows="4" cols="36"><?php echo validHtmlStr($monitor->EncoderParameters()) ?></textarea></td></tr>
|
||||
<tr><td><?php echo translate('RecordAudio') ?></td><td><input type="checkbox" name="newMonitor[RecordAudio]" value="1"<?php if ( $monitor->RecordAudio() ) { ?> checked="checked"<?php } ?>/></td></tr>
|
||||
<?php
|
||||
|
|
|
@ -279,7 +279,7 @@ foreach( array_map( 'basename', glob('skins/'.$current_skin.'/css/*',GLOB_ONLYDI
|
|||
<td class="colScheme"><?php echo makePopupLink( '?view=storage&id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Scheme()), $canEdit ) ?></td>
|
||||
<td class="colServer"><?php
|
||||
echo makePopupLink( '?view=storage&id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Name()), $canEdit ) ?></td>
|
||||
<td class="colDiskSpace"><?php echo human_filesize($Storage->disk_used_space()) . ' of ' . human_filesize($Storage->disk_total_space()) ?><?td>
|
||||
<td class="colDiskSpace"><?php echo human_filesize($Storage->disk_used_space()) . ' of ' . human_filesize($Storage->disk_total_space()) ?></td>
|
||||
<td class="colMark"><input type="checkbox" name="markIds[]" value="<?php echo $Storage->Id() ?>" onclick="configureDeleteButton(this);"<?php if ( !$canEdit ) { ?> disabled="disabled"<?php } ?>/></td>
|
||||
</tr>
|
||||
<?php } #end foreach Server ?>
|
||||
|
|
|
@ -105,7 +105,7 @@ while( $event = $result->fetch(PDO::FETCH_ASSOC) ) {
|
|||
} # end if has previous events
|
||||
if ( ! $Event->file_exists() ) {
|
||||
$EventsByMonitor[$event['MonitorId']]['FileMissing'][] = $Event;
|
||||
} else if ( ! filesize( $Event->Path().'/'.$Event->DefaultVideo() ) ) {
|
||||
} else if ( ! $Event->file_size() ) {
|
||||
$EventsByMonitor[$event['MonitorId']]['ZeroSize'][] = $Event;
|
||||
}
|
||||
$EventsByMonitor[$event['MonitorId']]['Events'][] = $Event;
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canView( 'Events' ) ) {
|
||||
$view = "error";
|
||||
if ( !canView('Events') ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -28,31 +28,31 @@ require_once('includes/Event.php');
|
|||
$eid = validInt($_REQUEST['eid']);
|
||||
|
||||
$sql = 'SELECT E.*,M.Name AS MonitorName,M.DefaultRate,M.DefaultScale FROM Events AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id WHERE E.Id = ?';
|
||||
$sql_values = array( $eid );
|
||||
$sql_values = array($eid);
|
||||
|
||||
if ( $user['MonitorIds'] ) {
|
||||
$monitor_ids = explode( ',', $user['MonitorIds'] );
|
||||
$sql .= ' AND MonitorId IN (' .implode( ',', array_fill(0,count($monitor_ids),'?') ) . ')';
|
||||
$sql_values = array_merge( $sql_values, $monitor_ids );
|
||||
$monitor_ids = explode(',', $user['MonitorIds']);
|
||||
$sql .= ' AND MonitorId IN ('.implode(',', array_fill(0,count($monitor_ids),'?')).')';
|
||||
$sql_values = array_merge($sql_values, $monitor_ids);
|
||||
}
|
||||
$event = dbFetchOne( $sql, NULL, $sql_values );
|
||||
$event = dbFetchOne($sql, NULL, $sql_values);
|
||||
|
||||
if ( isset( $_REQUEST['rate'] ) )
|
||||
if ( isset($_REQUEST['rate']) )
|
||||
$rate = validInt($_REQUEST['rate']);
|
||||
else
|
||||
$rate = reScale( RATE_BASE, $event['DefaultRate'], ZM_WEB_DEFAULT_RATE );
|
||||
if ( isset( $_REQUEST['scale'] ) )
|
||||
$rate = reScale(RATE_BASE, $event['DefaultRate'], ZM_WEB_DEFAULT_RATE);
|
||||
if ( isset($_REQUEST['scale']) )
|
||||
$scale = validInt($_REQUEST['scale']);
|
||||
else
|
||||
$scale = reScale( SCALE_BASE, $event['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
|
||||
$scale = reScale(SCALE_BASE, $event['DefaultScale'], ZM_WEB_DEFAULT_SCALE);
|
||||
|
||||
$Event = new Event( $event['Id'] );
|
||||
$Event = new Event($event['Id']);
|
||||
$eventPath = $Event->Path();
|
||||
|
||||
$videoFormats = array();
|
||||
$ffmpegFormats = preg_split( '/\s+/', ZM_FFMPEG_FORMATS );
|
||||
$ffmpegFormats = preg_split('/\s+/', ZM_FFMPEG_FORMATS);
|
||||
foreach ( $ffmpegFormats as $ffmpegFormat ) {
|
||||
if ( preg_match( '/^([^*]+)(\*\*?)$/', $ffmpegFormat, $matches ) ) {
|
||||
if ( preg_match('/^([^*]+)(\*\*?)$/', $ffmpegFormat, $matches) ) {
|
||||
$videoFormats[$matches[1]] = $matches[1];
|
||||
if ( !isset($videoFormat) && $matches[2] == '*' ) {
|
||||
$videoFormat = $matches[1];
|
||||
|
@ -63,42 +63,44 @@ foreach ( $ffmpegFormats as $ffmpegFormat ) {
|
|||
}
|
||||
|
||||
$videoFiles = array();
|
||||
if ( $dir = opendir( $eventPath ) ) {
|
||||
while ( ($file = readdir( $dir )) !== false ) {
|
||||
if ( $dir = opendir($eventPath) ) {
|
||||
while ( ($file = readdir($dir)) !== false ) {
|
||||
$file = $eventPath.'/'.$file;
|
||||
if ( is_file( $file ) ) {
|
||||
if ( preg_match( '/\.(?:'.join( '|', $videoFormats ).')$/', $file ) ) {
|
||||
if ( is_file($file) ) {
|
||||
if ( preg_match('/\.(?:'.join('|', $videoFormats).')$/', $file) ) {
|
||||
$videoFiles[] = $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir( $dir );
|
||||
closedir($dir);
|
||||
}
|
||||
|
||||
if ( isset($_REQUEST['deleteIndex']) ) {
|
||||
$deleteIndex = validInt($_REQUEST['deleteIndex']);
|
||||
unlink( $videoFiles[$deleteIndex] );
|
||||
unset( $videoFiles[$deleteIndex] );
|
||||
unlink($videoFiles[$deleteIndex]);
|
||||
unset($videoFiles[$deleteIndex]);
|
||||
}
|
||||
|
||||
if ( isset($_REQUEST['downloadIndex']) ) {
|
||||
// can't be output buffering, as this file might be large
|
||||
ob_end_clean();
|
||||
$downloadIndex = validInt($_REQUEST['downloadIndex']);
|
||||
header( 'Pragma: public' );
|
||||
header( 'Expires: 0' );
|
||||
header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
|
||||
header( 'Cache-Control: private', false ); // required by certain browsers
|
||||
header( 'Content-Description: File Transfer' );
|
||||
header( 'Content-disposition: attachment; filename="'.basename($videoFiles[$downloadIndex]).'"' ); // basename is required because the video index contains the path and firefox doesn't strip the path but simply replaces the slashes with an underscore.
|
||||
header( 'Content-Transfer-Encoding: binary' );
|
||||
header( 'Content-Type: application/force-download' );
|
||||
header( 'Content-Length: '.filesize($videoFiles[$downloadIndex]) );
|
||||
readfile( $videoFiles[$downloadIndex] );
|
||||
header('Pragma: public');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
header('Cache-Control: private', false); // required by certain browsers
|
||||
header('Content-Description: File Transfer');
|
||||
header('Content-disposition: attachment; filename="'.basename($videoFiles[$downloadIndex]).'"'); // basename is required because the video index contains the path and firefox doesn't strip the path but simply replaces the slashes with an underscore.
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
header('Content-Type: application/force-download');
|
||||
header('Content-Length: '.filesize($videoFiles[$downloadIndex]));
|
||||
readfile($videoFiles[$downloadIndex]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$focusWindow = true;
|
||||
|
||||
xhtmlHeaders(__FILE__, translate('Video') );
|
||||
xhtmlHeaders(__FILE__, translate('Video'));
|
||||
?>
|
||||
<body>
|
||||
<div id="page">
|
||||
|
@ -112,30 +114,30 @@ xhtmlHeaders(__FILE__, translate('Video') );
|
|||
<?php
|
||||
if ( isset($_REQUEST['showIndex']) ) {
|
||||
$showIndex = validInt($_REQUEST['showIndex']);
|
||||
preg_match( '/([^\/]+)\.([^.]+)$/', $videoFiles[$showIndex], $matches );
|
||||
preg_match('/([^\/]+)\.([^.]+)$/', $videoFiles[$showIndex], $matches);
|
||||
$name = $matches[1];
|
||||
$videoFormat = $matches[2];
|
||||
?>
|
||||
<h3 id="videoFile"><?php echo substr( $videoFiles[$showIndex], strlen(ZM_DIR_EVENTS)+1 ) ?></h3>
|
||||
<div id="imageFeed"><?php outputVideoStream( 'videoStream', $videoFiles[$showIndex], validInt($_REQUEST['width']), validInt($_REQUEST['height']), $videoFormat, $name ) ?></div>
|
||||
<h3 id="videoFile"><?php echo substr($videoFiles[$showIndex], strlen(ZM_DIR_EVENTS)+1) ?></h3>
|
||||
<div id="imageFeed"><?php outputVideoStream('videoStream', $videoFiles[$showIndex], validInt($_REQUEST['width']), validInt($_REQUEST['height']), $videoFormat, $name) ?></div>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<input type="hidden" name="id" value="<?php echo $event['Id'] ?>"/>
|
||||
<table id="contentTable" class="minor" cellspacing="0">
|
||||
<table id="contentTable" class="minor">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('VideoFormat') ?></th>
|
||||
<td><?php echo buildSelect( "videoFormat", $videoFormats ) ?></td>
|
||||
<td><?php echo buildSelect('videoFormat', $videoFormats) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('FrameRate') ?></th>
|
||||
<td><?php echo buildSelect( "rate", $rates ) ?></td>
|
||||
<td><?php echo buildSelect('rate', $rates) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('VideoSize') ?></th>
|
||||
<td><?php echo buildSelect( "scale", $scales ) ?></td>
|
||||
<td><?php echo buildSelect('scale', $scales) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('OverwriteExisting') ?></th>
|
||||
|
@ -143,16 +145,22 @@ if ( isset($_REQUEST['showIndex']) ) {
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<input type="button" value="<?php echo translate('GenerateVideo') ?>" onclick="generateVideo( this.form );"<?php if ( !ZM_OPT_FFMPEG ) { ?> disabled="disabled"<?php } ?>/>
|
||||
<input type="button" value="<?php echo translate('GenerateVideo') ?>" onclick="generateVideo(this.form);"<?php if ( !ZM_OPT_FFMPEG ) { ?> disabled="disabled"<?php } ?>/>
|
||||
</form>
|
||||
<?php
|
||||
if ( isset($_REQUEST['generated']) ) {
|
||||
?>
|
||||
<h2 id="videoProgress" class="<?php echo $_REQUEST['generated']?'infoText':'errorText' ?>"><span id="videoProgressText"><?php echo $_REQUEST['generated']?translate('VideoGenSucceeded'):translate('VideoGenFailed') ?></span><span id="videoProgressTicker"></span></h2>
|
||||
<h2 id="videoProgress" class="<?php echo $_REQUEST['generated']?'infoText':'errorText' ?>">
|
||||
<span id="videoProgressText"><?php echo $_REQUEST['generated']?translate('VideoGenSucceeded'):translate('VideoGenFailed') ?></span>
|
||||
<span id="videoProgressTicker"></span>
|
||||
</h2>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<h2 id="videoProgress" class="hidden warnText"><span id="videoProgressText"><?php echo translate('GeneratingVideo') ?></span><span id="videoProgressTicker"></span></h2>
|
||||
<h2 id="videoProgress" class="hidden warnText">
|
||||
<span id="videoProgressText"><?php echo translate('GeneratingVideo') ?></span>
|
||||
<span id="videoProgressTicker"></span>
|
||||
</h2>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
@ -164,7 +172,7 @@ if ( isset($_REQUEST['showIndex']) ) {
|
|||
<?php
|
||||
} else {
|
||||
?>
|
||||
<table id="videoTable" class="major" cellspacing="0">
|
||||
<table id="videoTable" class="major">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="row"><?php echo translate('Format') ?></th>
|
||||
|
@ -178,29 +186,29 @@ if ( isset($_REQUEST['showIndex']) ) {
|
|||
<?php
|
||||
$index = 0;
|
||||
foreach ( $videoFiles as $file ) {
|
||||
if ( filesize( $file ) > 0 ) {
|
||||
preg_match( '/^(.+)-((?:r[_\d]+)|(?:F[_\d]+))-((?:s[_\d]+)|(?:S[0-9a-z]+))\.([^.]+)$/', $file, $matches );
|
||||
if ( preg_match( '/^r(.+)$/', $matches[2], $temp_matches ) ) {
|
||||
if ( filesize($file) > 0 ) {
|
||||
preg_match('/^(.+)-((?:r[_\d]+)|(?:F[_\d]+))-((?:s[_\d]+)|(?:S[0-9a-z]+))\.([^.]+)$/', $file, $matches);
|
||||
if ( preg_match('/^r(.+)$/', $matches[2], $temp_matches) ) {
|
||||
$rate = (int)(100 * preg_replace( '/_/', '.', $temp_matches[1] ) );
|
||||
$rateText = isset($rates[$rate])?$rates[$rate]:($rate."x");
|
||||
} elseif ( preg_match( '/^F(.+)$/', $matches[2], $temp_matches ) ) {
|
||||
$rateText = $temp_matches[1]."fps";
|
||||
} elseif ( preg_match('/^F(.+)$/', $matches[2], $temp_matches) ) {
|
||||
$rateText = $temp_matches[1].'fps';
|
||||
}
|
||||
if ( preg_match( '/^s(.+)$/', $matches[3], $temp_matches ) ) {
|
||||
$scale = (int)(100 * preg_replace( '/_/', '.', $temp_matches[1] ) );
|
||||
$scaleText = isset($scales[$scale])?$scales[$scale]:($scale."x");
|
||||
} elseif ( preg_match( '/^S(.+)$/', $matches[3], $temp_matches ) ) {
|
||||
if ( preg_match('/^s(.+)$/', $matches[3], $temp_matches) ) {
|
||||
$scale = (int)(100 * preg_replace('/_/', '.', $temp_matches[1]) );
|
||||
$scaleText = isset($scales[$scale])?$scales[$scale]:($scale.'x');
|
||||
} elseif ( preg_match('/^S(.+)$/', $matches[3], $temp_matches) ) {
|
||||
$scaleText = $temp_matches[1];
|
||||
}
|
||||
$width = $scale?reScale( $event['Width'], $scale ):$event['Width'];
|
||||
$height = $scale?reScale( $event['Height'], $scale ):$event['Height'];
|
||||
$width = $scale?reScale($event['Width'], $scale):$event['Width'];
|
||||
$height = $scale?reScale($event['Height'], $scale):$event['Height'];
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo $matches[4] ?></td>
|
||||
<td><?php echo filesize( $file ) ?></td>
|
||||
<td><?php echo filesize($file) ?></td>
|
||||
<td><?php echo $rateText ?></td>
|
||||
<td><?php echo $scaleText ?></td>
|
||||
<td><?php echo makePopupLink( '?view='.$view.'&eid='.$event['Id'].'&width='.$width.'&height='.$height.'&showIndex='.$index, 'zmVideo'.$event['Id'].'-'.$scale, array( 'videoview', $width, $height ), translate('View') ); ?> / <a href="<?php echo substr( $file, strlen(ZM_DIR_EVENTS)+1 ) ?>" onclick="downloadVideo( <?php echo $index ?> ); return( false );"><?php echo translate('Download') ?></a> / <a href="#" onclick="deleteVideo( <?php echo $index ?> ); return( false );"><?php echo translate('Delete') ?></a></td>
|
||||
<td><?php echo makePopupLink('?view='.$view.'&eid='.$event['Id'].'&width='.$width.'&height='.$height.'&showIndex='.$index, 'zmVideo'.$event['Id'].'-'.$scale, array( 'videoview', $width, $height ), translate('View') ); ?> / <a href="<?php echo substr( $file, strlen(ZM_DIR_EVENTS)+1 ) ?>" onclick="downloadVideo( <?php echo $index ?> ); return( false );"><?php echo translate('Download') ?></a> / <a href="#" onclick="deleteVideo( <?php echo $index ?> ); return( false );"><?php echo translate('Delete') ?></a></td>
|
||||
</tr>
|
||||
<?php
|
||||
$index++;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canView( 'Events' ) ) {
|
||||
if ( !canView('Events') ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
@ -43,11 +43,15 @@ if ( $archivetype ) {
|
|||
if ( $mimetype ) {
|
||||
$filename = "zmExport.$file_ext";
|
||||
$filename_path = ZM_DIR_EXPORTS.'/'.$filename;
|
||||
Logger::Debug("downloading archive from $filename_path");
|
||||
if ( is_readable($filename_path) ) {
|
||||
header( "Content-type: application/$mimetype" );
|
||||
header( "Content-Disposition: attachment; filename=$filename");
|
||||
header("Content-type: application/$mimetype" );
|
||||
header("Content-Disposition: inline; filename=$filename");
|
||||
header('Content-Length: ' . filesize($filename_path) );
|
||||
set_time_limit(0);
|
||||
readfile( $filename_path );
|
||||
if ( ! @readfile( $filename_path ) ) {
|
||||
Error("Error sending $filename_path");
|
||||
}
|
||||
} else {
|
||||
Error("$filename_path does not exist or is not readable.");
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
// If both scale and either width or height are specified, scale is ignored
|
||||
//
|
||||
|
||||
if ( !canView( 'Events' ) ) {
|
||||
if ( !canView('Events') ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
@ -60,80 +60,96 @@ $path = null;
|
|||
|
||||
if ( empty($_REQUEST['path']) ) {
|
||||
|
||||
if ( ! empty($_REQUEST['fid']) ) {
|
||||
if ( $_REQUEST['fid'] == 'snapshot' ) {
|
||||
$Event = new Event( $_REQUEST['eid'] );
|
||||
$Frame = new Frame();
|
||||
$Frame->FrameId('snapshot');
|
||||
$path = $Event->Path().'/snapshot.jpg';
|
||||
} else {
|
||||
$show = empty($_REQUEST['show']) ? 'capture' : $_REQUEST['show'];
|
||||
|
||||
$show = empty($_REQUEST['show']) ? 'capture' : $_REQUEST['show'];
|
||||
|
||||
if ( ! empty($_REQUEST['eid'] ) ) {
|
||||
$Event = Event::find_one(array('Id'=> $_REQUEST['eid']));
|
||||
if ( ! $Event ) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
Fatal('Event ' . $_REQUEST['eid'].' Not found');
|
||||
return;
|
||||
}
|
||||
|
||||
$Frame = Frame::find_one(array('EventId'=>$_REQUEST['eid'], 'FrameId'=>$_REQUEST['fid']));
|
||||
if ( ! $Frame ) {
|
||||
$previousBulkFrame = dbFetchOne('SELECT * FROM Frames WHERE EventId=? AND FrameId < ? ORDER BY FrameID DESC LIMIT 1', NULL, array($_REQUEST['eid'], $_REQUEST['fid'] ) );
|
||||
$nextBulkFrame = dbFetchOne( "SELECT * FROM Frames WHERE EventId=? AND FrameId > ? ORDER BY FrameID ASC LIMIT 1", NULL, array($_REQUEST['eid'], $_REQUEST['fid'] ) );
|
||||
if ( $previousBulkFrame and $nextBulkFrame ) {
|
||||
$Frame = new Frame( $previousBulkFrame );
|
||||
$Frame->FrameId( $_REQUEST['fid'] );
|
||||
|
||||
$percentage = ($Frame->FrameId() - $previousBulkFrame['FrameId']) / ($nextBulkFrame['FrameId'] - $previousBulkFrame['FrameId']);
|
||||
|
||||
$Frame->Delta( $previousBulkFrame['Delta'] + floor( 100* ( $nextBulkFrame['Delta'] - $previousBulkFrame['Delta'] ) * $percentage )/100 );
|
||||
Logger::Debug("Got virtual frame from Bulk Frames previous delta: " . $previousBulkFrame['Delta'] . " + nextdelta:" . $nextBulkFrame['Delta'] . ' - ' . $previousBulkFrame['Delta'] . ' * ' . $percentage );
|
||||
} else {
|
||||
Fatal("No Frame found for event(".$_REQUEST['eid'].") and frame id(".$_REQUEST['fid'].")");
|
||||
}
|
||||
}
|
||||
// Frame can be non-existent. We have Bulk frames. So now we should try to load the bulk frame
|
||||
|
||||
} else {
|
||||
# If we are only specifying fid, then the fid must be the primary key into the frames table. But when the event is specified, then it is the frame #
|
||||
$Frame = Frame::find_one(array('Id'=>$_REQUEST['fid']));
|
||||
if ( ! $Frame ) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
Fatal('Frame ' . $_REQUEST['fid'] . ' Not Found');
|
||||
return;
|
||||
}
|
||||
|
||||
$Event = Event::find_one(array('Id'=>$Frame->EventId()));
|
||||
if ( ! $Event ) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
Fatal('Event ' . $Frame->EventId() . ' Not Found');
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
$path = $Event->Path().'/'.sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d',$Frame->FrameId()).'-'.$show.'.jpg';
|
||||
}
|
||||
|
||||
} else {
|
||||
if ( empty($_REQUEST['fid']) ) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
Fatal('No Frame ID specified');
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! file_exists( $path ) ) {
|
||||
Logger::Debug( "$path does not exist");
|
||||
# Generate the frame JPG
|
||||
if ( !empty($_REQUEST['eid']) ) {
|
||||
$Event = Event::find_one(array('Id'=>$_REQUEST['eid']));
|
||||
if ( ! $Event ) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
Fatal('Event ' . $_REQUEST['eid'].' Not found');
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $_REQUEST['fid'] == 'snapshot' ) {
|
||||
$Frame = Frame::find_one(array('EventId'=>$_REQUEST['eid'], 'Score'=>$Event->MaxScore()));
|
||||
if ( ! $Frame )
|
||||
$Frame = Frame::find_one(array('EventId'=>$_REQUEST['eid']));
|
||||
if ( ! $Frame ) {
|
||||
$Frame = new Frame();
|
||||
$Frame->Delta(1);
|
||||
$Frame->FrameId('snapshot');
|
||||
}
|
||||
$Monitor = $Event->Monitor();
|
||||
if ( $Monitor->SaveJPEGs() & 1 ) {
|
||||
# If we store Frames as jpgs, then we don't store a snapshot
|
||||
$path = $Event->Path().'/'.sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d',$Frame->FrameId()).'-'.$show.'.jpg';
|
||||
} else {
|
||||
$path = $Event->Path().'/snapshot.jpg';
|
||||
}
|
||||
} else {
|
||||
|
||||
$Frame = Frame::find_one(array('EventId'=>$_REQUEST['eid'], 'FrameId'=>$_REQUEST['fid']));
|
||||
if ( ! $Frame ) {
|
||||
$previousBulkFrame = dbFetchOne(
|
||||
'SELECT * FROM Frames WHERE EventId=? AND FrameId < ? ORDER BY FrameID DESC LIMIT 1',
|
||||
NULL, array($_REQUEST['eid'], $_REQUEST['fid'])
|
||||
);
|
||||
$nextBulkFrame = dbFetchOne(
|
||||
'SELECT * FROM Frames WHERE EventId=? AND FrameId > ? ORDER BY FrameID ASC LIMIT 1',
|
||||
NULL, array($_REQUEST['eid'], $_REQUEST['fid'])
|
||||
);
|
||||
if ( $previousBulkFrame and $nextBulkFrame ) {
|
||||
$Frame = new Frame($previousBulkFrame);
|
||||
$Frame->FrameId($_REQUEST['fid']);
|
||||
|
||||
$percentage = ($Frame->FrameId() - $previousBulkFrame['FrameId']) / ($nextBulkFrame['FrameId'] - $previousBulkFrame['FrameId']);
|
||||
|
||||
$Frame->Delta($previousBulkFrame['Delta'] + floor( 100* ( $nextBulkFrame['Delta'] - $previousBulkFrame['Delta'] ) * $percentage )/100);
|
||||
Logger::Debug("Got virtual frame from Bulk Frames previous delta: " . $previousBulkFrame['Delta'] . " + nextdelta:" . $nextBulkFrame['Delta'] . ' - ' . $previousBulkFrame['Delta'] . ' * ' . $percentage );
|
||||
} else {
|
||||
Fatal('No Frame found for event('.$_REQUEST['eid'].') and frame id('.$_REQUEST['fid'].')');
|
||||
}
|
||||
}
|
||||
// Frame can be non-existent. We have Bulk frames. So now we should try to load the bulk frame
|
||||
$path = $Event->Path().'/'.sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d',$Frame->FrameId()).'-'.$show.'.jpg';
|
||||
}
|
||||
|
||||
} else {
|
||||
# If we are only specifying fid, then the fid must be the primary key into the frames table. But when the event is specified, then it is the frame #
|
||||
$Frame = Frame::find_one(array('Id'=>$_REQUEST['fid']));
|
||||
if ( ! $Frame ) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
Fatal('Frame ' . $_REQUEST['fid'] . ' Not Found');
|
||||
return;
|
||||
}
|
||||
|
||||
$Event = Event::find_one(array('Id'=>$Frame->EventId()));
|
||||
if ( ! $Event ) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
Fatal('Event ' . $Frame->EventId() . ' Not Found');
|
||||
return;
|
||||
}
|
||||
$path = $Event->Path().'/'.sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d',$Frame->FrameId()).'-'.$show.'.jpg';
|
||||
} # end if have eid
|
||||
|
||||
if ( ! file_exists($path) ) {
|
||||
Logger::Debug("$path does not exist");
|
||||
# Generate the frame JPG
|
||||
if ( $show == 'capture' and $Event->DefaultVideo() ) {
|
||||
if ( ! file_exists($Event->Path().'/'.$Event->DefaultVideo()) ) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
Fatal("Can't create frame images from video becuase there is no video file for this event at (".$Event->Path().'/'.$Event->DefaultVideo() );
|
||||
Fatal("Can't create frame images from video because there is no video file for this event at (".$Event->Path().'/'.$Event->DefaultVideo() );
|
||||
}
|
||||
$command ='ffmpeg -ss '. $Frame->Delta() .' -i '.$Event->Path().'/'.$Event->DefaultVideo().' -frames:v 1 '.$path;
|
||||
#$command ='ffmpeg -ss '. $Frame->Delta() .' -i '.$Event->Path().'/'.$Event->DefaultVideo().' -vf "select=gte(n\\,'.$Frame->FrameId().'),setpts=PTS-STARTPTS" '.$path;
|
||||
#$command ='ffmpeg -v 0 -i '.$Storage->Path().'/'.$Event->Path().'/'.$Event->DefaultVideo().' -vf "select=gte(n\\,'.$Frame->FrameId().'),setpts=PTS-STARTPTS" '.$path;
|
||||
Logger::Debug( "Running $command" );
|
||||
Logger::Debug("Running $command");
|
||||
$output = array();
|
||||
$retval = 0;
|
||||
exec( $command, $output, $retval );
|
||||
|
@ -142,13 +158,15 @@ Logger::Debug("Got virtual frame from Bulk Frames previous delta: " . $previousB
|
|||
header('HTTP/1.0 404 Not Found');
|
||||
Fatal("Can't create frame images from video for this event (".$Event->DefaultVideo() );
|
||||
}
|
||||
$Event->DiskSpace( null );
|
||||
# Generating an image file will use up more disk space, so update the Event record.
|
||||
$Event->DiskSpace(null);
|
||||
$Event->save();
|
||||
} else {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
Fatal("Can't create frame images from video becuase there is no video file for this event (".$Event->DefaultVideo() );
|
||||
Fatal("Can't create frame $show images from video because there is no video file for this event at ".
|
||||
$Event->Path().'/'.$Event->DefaultVideo() );
|
||||
}
|
||||
}
|
||||
} # end if ! file_exists($path)
|
||||
|
||||
} else {
|
||||
Warning('Loading images by path is deprecated');
|
||||
|
@ -157,10 +175,10 @@ Logger::Debug("Got virtual frame from Bulk Frames previous delta: " . $previousB
|
|||
$pos = strpos($path, $dir_events);
|
||||
|
||||
if ( $pos == 0 && $pos !== false ) {
|
||||
if ( ! empty( $user['MonitorIds'] ) ) {
|
||||
if ( ! empty($user['MonitorIds']) ) {
|
||||
$imageOk = false;
|
||||
$pathMonId = substr( $path, 0, strspn( $path, '1234567890' ) );
|
||||
foreach ( preg_split( '/["\'\s]*,["\'\s]*/', $user['MonitorIds'] ) as $monId ) {
|
||||
$pathMonId = substr($path, 0, strspn($path, '1234567890'));
|
||||
foreach ( preg_split('/["\'\s]*,["\'\s]*/', $user['MonitorIds']) as $monId ) {
|
||||
if ( $pathMonId == $monId ) {
|
||||
$imageOk = true;
|
||||
break;
|
||||
|
@ -172,39 +190,39 @@ Logger::Debug("Got virtual frame from Bulk Frames previous delta: " . $previousB
|
|||
} else {
|
||||
$errorText = 'Invalid image path';
|
||||
}
|
||||
if ( ! file_exists( $path ) ) {
|
||||
if ( ! file_exists($path) ) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
Fatal("Image not found at $path");
|
||||
}
|
||||
}
|
||||
|
||||
$scale=0;
|
||||
if( !empty($_REQUEST['scale']) ) {
|
||||
if (is_numeric($_REQUEST['scale'])) {
|
||||
if ( !empty($_REQUEST['scale']) ) {
|
||||
if ( is_numeric($_REQUEST['scale']) ) {
|
||||
$x = $_REQUEST['scale'];
|
||||
if($x >= 1 and $x <= 400)
|
||||
if ( $x >= 1 and $x <= 400 )
|
||||
$scale=$x;
|
||||
}
|
||||
}
|
||||
|
||||
$width=0;
|
||||
if ( !empty($_REQUEST['width']) ) {
|
||||
if (is_numeric($_REQUEST['width'])) {
|
||||
if ( is_numeric($_REQUEST['width']) ) {
|
||||
$x = $_REQUEST['width'];
|
||||
if($x >= 10 and $x <= 8000)
|
||||
if ( $x >= 10 and $x <= 8000 )
|
||||
$width=$x;
|
||||
}
|
||||
}
|
||||
$height=0;
|
||||
if( !empty($_REQUEST['height']) ) {
|
||||
if (is_numeric($_REQUEST['height'])) {
|
||||
if ( !empty($_REQUEST['height']) ) {
|
||||
if ( is_numeric($_REQUEST['height']) ) {
|
||||
$x = $_REQUEST['height'];
|
||||
if($x >= 10 and $x <= 8000)
|
||||
if ( $x >= 10 and $x <= 8000 )
|
||||
$height=$x;
|
||||
}
|
||||
}
|
||||
|
||||
header( 'Content-type: image/jpeg' );
|
||||
header('Content-type: image/jpeg');
|
||||
|
||||
# This is so that Save Image As give a useful filename
|
||||
if ( $Event ) {
|
||||
|
@ -215,19 +233,19 @@ ob_clean();
|
|||
flush();
|
||||
|
||||
if ( $errorText ) {
|
||||
Error( $errorText );
|
||||
Error($errorText);
|
||||
} else {
|
||||
if ( ( $scale==0 || $scale==100 ) && $width==0 && $height==0 ) {
|
||||
if ( ! readfile( $path ) ) {
|
||||
Error("No bytes read from ". $path );
|
||||
if ( !readfile($path) ) {
|
||||
Error('No bytes read from '. $path);
|
||||
}
|
||||
} else {
|
||||
Logger::Debug("Doing a scaled image: scale($scale) width($width) height($height)");
|
||||
$i = 0;
|
||||
if ( ! ( $width && $height ) ) {
|
||||
$i = imagecreatefromjpeg( $path );
|
||||
$oldWidth = imagesx( $i );
|
||||
$oldHeight = imagesy( $i );
|
||||
$i = imagecreatefromjpeg($path);
|
||||
$oldWidth = imagesx($i);
|
||||
$oldHeight = imagesy($i);
|
||||
if ( $width == 0 && $height == 0 ) { // scale has to be set to get here with both zero
|
||||
$width = $oldWidth * $scale / 100.0;
|
||||
$height= $oldHeight * $scale / 100.0;
|
||||
|
@ -237,23 +255,23 @@ if ( $errorText ) {
|
|||
$height = ($width * $oldHeight) / $oldWidth;
|
||||
}
|
||||
if ( $width == $oldWidth && $height == $oldHeight) {
|
||||
Warning( 'No change to width despite scaling.' );
|
||||
Warning('No change to width despite scaling.');
|
||||
}
|
||||
}
|
||||
|
||||
# Slight optimisation, thumbnails always specify width and height, so we can cache them.
|
||||
$scaled_path = preg_replace('/\.jpg$/', "-${width}x${height}.jpg", $path );
|
||||
if ( ! file_exists( $scaled_path ) or ! readfile( $scaled_path ) ) {
|
||||
Logger::Debug( "Cached scaled image does not exist at $scaled_path or is no good.. Creating it");
|
||||
if ( ! file_exists($scaled_path) or ! readfile($scaled_path) ) {
|
||||
Logger::Debug("Cached scaled image does not exist at $scaled_path or is no good.. Creating it");
|
||||
ob_start();
|
||||
if ( ! $i )
|
||||
$i = imagecreatefromjpeg( $path );
|
||||
$iScale = imagescale( $i, $width, $height );
|
||||
imagejpeg( $iScale );
|
||||
imagedestroy( $i );
|
||||
imagedestroy( $iScale );
|
||||
$i = imagecreatefromjpeg($path);
|
||||
$iScale = imagescale($i, $width, $height);
|
||||
imagejpeg($iScale);
|
||||
imagedestroy($i);
|
||||
imagedestroy($iScale);
|
||||
$scaled_jpeg_data = ob_get_contents();
|
||||
file_put_contents( $scaled_path, $scaled_jpeg_data );
|
||||
file_put_contents($scaled_path, $scaled_jpeg_data);
|
||||
ob_end_clean();
|
||||
echo $scaled_jpeg_data;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue