Merge branch 'master' into add_alarmed_zone_to_filters

pull/2839/head
Isaac Connor 2020-01-22 13:45:37 -05:00
commit 9d41334e8f
78 changed files with 2005 additions and 1539 deletions

View File

@ -33,24 +33,23 @@ install:
env:
- SMPFLAGS=-j4 OS=el DIST=7
- SMPFLAGS=-j4 OS=el DIST=8
- SMPFLAGS=-j4 OS=fedora DIST=29 DOCKER_REPO=knnniggett/packpack
- SMPFLAGS=-j4 OS=el DIST=8 DOCKER_REPO=knnniggett/packpack
- SMPFLAGS=-j4 OS=fedora DIST=30
- SMPFLAGS=-j4 OS=ubuntu DIST=trusty DOCKER_REPO=iconzm/packpack USE_SFTP=yes
- SMPFLAGS=-j4 OS=ubuntu DIST=xenial DOCKER_REPO=iconzm/packpack USE_SFTP=yes
- SMPFLAGS=-j4 OS=ubuntu DIST=bionic DOCKER_REPO=iconzm/packpack USE_SFTP=yes
- SMPFLAGS=-j4 OS=ubuntu DIST=disco DOCKER_REPO=iconzm/packpack USE_SFTP=yes
- SMPFLAGS=-j4 OS=ubuntu DIST=eoan DOCKER_REPO=iconzm/packpack USE_SFTP=yes
- SMPFLAGS=-j4 OS=debian DIST=jessie DOCKER_REPO=iconzm/packpack USE_SFTP=yes
- SMPFLAGS=-j4 OS=debian DIST=stretch DOCKER_REPO=iconzm/packpack USE_SFTP=yes
- SMPFLAGS=-j4 OS=debian DIST=buster DOCKER_REPO=iconzm/packpack USE_SFTP=yes
- SMPFLAGS=-j4 OS=fedora DIST=31
- SMPFLAGS=-j4 OS=ubuntu DIST=trusty DOCKER_REPO=iconzm/packpack
- SMPFLAGS=-j4 OS=ubuntu DIST=xenial DOCKER_REPO=iconzm/packpack
- SMPFLAGS=-j4 OS=ubuntu DIST=bionic DOCKER_REPO=iconzm/packpack
- SMPFLAGS=-j4 OS=ubuntu DIST=disco DOCKER_REPO=iconzm/packpack
- SMPFLAGS=-j4 OS=ubuntu DIST=eoan DOCKER_REPO=iconzm/packpack
- SMPFLAGS=-j4 OS=debian DIST=jessie DOCKER_REPO=iconzm/packpack
- SMPFLAGS=-j4 OS=debian DIST=stretch DOCKER_REPO=iconzm/packpack
- SMPFLAGS=-j4 OS=debian DIST=buster DOCKER_REPO=iconzm/packpack
- SMPFLAGS=-j4 OS=ubuntu DIST=trusty ARCH=i386
- SMPFLAGS=-j4 OS=ubuntu DIST=xenial ARCH=i386
- SMPFLAGS=-j4 OS=ubuntu DIST=bionic ARCH=i386
- SMPFLAGS=-j4 OS=ubuntu DIST=disco ARCH=i386
- SMPFLAGS=-j4 OS=debian DIST=buster ARCH=i386
- SMPFLAGS=-j4 OS=debian DIST=stretch ARCH=i386
- SMPFLAGS=-j4 OS=raspbian DIST=stretch ARCH=armhf DOCKER_REPO=knnniggett/packpack
- SMPFLAGS=-j4 OS=eslint DIST=eslint
compiler:
- gcc
@ -58,12 +57,6 @@ services:
- mysql
- docker
jobs:
include:
- name: eslint
install: npm install -g eslint@5.12.0 eslint-config-google@0.11.0 eslint-plugin-html@5.0.0 eslint-plugin-php-markup@0.2.5
script: eslint --ext .php,.js .
script:
- utils/packpack/startpackpack.sh

View File

@ -434,6 +434,7 @@ DROP TABLE IF EXISTS `Monitors`;
CREATE TABLE `Monitors` (
`Id` int(10) unsigned NOT NULL auto_increment,
`Name` varchar(64) NOT NULL default '',
`Notes` TEXT,
`ServerId` int(10) unsigned,
`StorageId` smallint(5) unsigned default 0,
`Type` enum('Local','Remote','File','Ffmpeg','Libvlc','cURL','WebSite','NVSocket') NOT NULL default 'Local',

12
db/zm_update-1.33.16.sql Normal file
View File

@ -0,0 +1,12 @@
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Monitors'
AND column_name = 'Notes'
) > 0,
"SELECT 'Column Notes already exists in Monitors'",
"ALTER TABLE `Monitors` ADD `Notes` TEXT AFTER `Name`"
));
PREPARE stmt FROM @s;
EXECUTE stmt;

5
db/zm_update-1.34.0.sql Normal file
View File

@ -0,0 +1,5 @@
--
-- This updates a 1.33.16 database to 1.34.0
--
-- No changes required
--

View File

@ -22,14 +22,10 @@ What's New
switching between httpd <-> nginx requires manaully changing ownership of
all event folders and the php session folder after the change.
4. If you have installed ZoneMinder from the FedBerry repositories, this build
of ZoneMinder has support for Raspberry Pi hardware acceleration when using
ffmpeg. Unforunately, there is a problem with the same hardware acceleration
when using libvlc. Consequently, libvlc support in this build of ZoneMinder
has been disabled until the problem is resolved. See the following bug
report for details: https://trac.videolan.org/vlc/ticket/18594
4. The timezone must now be set from the ZoneMinder web console. See the
appropriate README, mentioned in the next step, for details.
5. Continue on to the next README that corresponds to the chosen webserver:
6. Continue on to the next README that corresponds to your chosen webserver:
README.httpd - Follow these steps when using Apache
README.nginx - Follow these steps when using Nginx

View File

@ -36,20 +36,17 @@ NOTE: EL7 users should replace "dnf" with "yum" in the instructions below.
sudo chown root:apache *.conf
sudo chmod 640 *.conf
4. Edit /etc/php.ini, uncomment the date.timezone line, and add your local
timezone. PHP will complain loudly if this is not set, or if it is set
incorrectly, and these complaints will show up in the zoneminder logging
system as errors.
4. Manually setting the timezone in /etc/php.ini is deprecated.
If you are not sure of the proper timezone specification to use, look at
http://php.net/date.timezone
Instead, navigate to Options -> System from the ZoneMinder web console.
Do this after completing step 10, below.
Note that timezone errors will appear in the ZoneMinder log until this
has been completed.
5. Disable SELinux
We currently do not have the resources to create and maintain an accurate
SELinux policy for ZoneMinder on Fedora. We will gladly accept pull
reqeusts from anyone who wishes to do the work. In the meantime, SELinux
will need to be disabled or put into permissive mode.
SELinux must be disabled or put into permissive mode. This is not optional!
To immediately disbale SELinux for the current seesion, issue the following
from the command line:
@ -166,3 +163,11 @@ Upgrades
sudo systemctl restart httpd
sudo systemctl start zoneminder
6. Manually setting the timezone in /etc/php.ini is deprecated.
Instead, navigate to Options -> System from the ZoneMinder web console.
Do this now.
Note that timezone errors will appear in the ZoneMinder log until this
has been completed.

View File

@ -34,13 +34,13 @@ New installs
sudo chown root:nginx *.conf
sudo chmod 640 *.conf
4. Edit /etc/php.ini, uncomment the date.timezone line, and add your local
timezone. PHP will complain loudly if this is not set, or if it is set
incorrectly, and these complaints will show up in the zoneminder logging
system as errors.
4. Manually setting the timezone in /etc/php.ini is deprecated.
If you are not sure of the proper timezone specification to use, look at
http://php.net/date.timezone
Instead, navigate to Options -> System from the ZoneMinder web console.
Do this after completing step 10, below.
Note that timezone errors will appear in the ZoneMinder log until this
has been completed.
5. Disable SELinux
@ -169,3 +169,11 @@ Upgrades
sudo systemctl restart php-fpm
sudo systemctl start zoneminder
6. Manually setting the timezone in /etc/php.ini is deprecated.
Instead, navigate to Options -> System from the ZoneMinder web console.
Do this now.
Note that timezone errors will appear in the ZoneMinder log until this
has been completed.

View File

@ -14,16 +14,21 @@
# This will tell zoneminder's cmake process we are building against a known distro
%global zmtargetdistro %{?rhel:el%{rhel}}%{!?rhel:fc%{fedora}}
# Fedora >= 25 needs apcu backwards compatibility module
%if 0%{?fedora} >= 25
# Fedora needs apcu backwards compatibility module
%if 0%{?fedora}
%global with_apcu_bc 1
%endif
# Newer php's keep json functions in a subpackage
%if 0%{?fedora} || 0%{?rhel} >= 8
%global with_php_json 1
%endif
# The default for everything but el7 these days
%global _hardened_build 1
Name: zoneminder
Version: 1.33.15
Version: 1.34.0
Release: 1%{?dist}
Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons
@ -105,7 +110,7 @@ Summary: Common files for ZoneMinder, not tied to a specific web server
Requires: php-mysqli
Requires: php-common
Requires: php-gd
%{?fedora:Requires: php-json}
%{?with_php_json:Requires: php-json}
Requires: php-pecl-apcu
%{?with_apcu_bc:Requires: php-pecl-apcu-bc}
Requires: cambozola
@ -411,29 +416,20 @@ EOF
%dir %attr(755,nginx,nginx) %{_localstatedir}/spool/zoneminder-upload
%changelog
* Sun Dec 08 2019 Isaac Connor <isaac@zoneminder.com> - 1.33.15-1
- Bump to 1.33.15 Development
* Sat Jan 18 2020 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.34.0-1
- 1.34.0 Release
* Sun Aug 11 2019 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.33.14-1
- Bump to 1.33.13 Development
* Tue Dec 17 2019 Leigh Scott <leigh123linux@gmail.com> - 1.32.3-5
- Mass rebuild for x264
* Sun Jul 07 2019 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.33.12-1
- Bump to 1.33.12 Development
* Wed Aug 07 2019 Leigh Scott <leigh123linux@gmail.com> - 1.32.3-4
- Rebuild for new ffmpeg version
* Sun Jun 23 2019 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.33.9-1
- Bump to 1.33.9 Development
* Tue Mar 12 2019 Sérgio Basto <sergio@serjux.com> - 1.32.3-3
- Mass rebuild for x264
* Tue Apr 30 2019 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.33.8-1
- Bump to 1.33.8 Development
* Sun Apr 07 2019 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.33.6-1
- Bump to 1.33.6 Development
* Sat Mar 30 2019 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.33.4-1
- Bump to 1.33.4 Development
* Tue Dec 11 2018 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.33.0-1
- Bump to 1.33.0 Development
* Tue Mar 05 2019 RPM Fusion Release Engineering <leigh123linux@gmail.com> - 1.32.3-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Sat Dec 08 2018 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.32.3-1
- 1.32.3 Release

View File

@ -6,6 +6,7 @@ ScriptAlias /zm/cgi-bin "/usr/lib/zoneminder/cgi-bin"
Require all granted
</Directory>
# Order matters. This alias must come first.
Alias /zm/cache /var/cache/zoneminder/cache
<Directory /var/cache/zoneminder/cache>

View File

@ -61,7 +61,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
,libjson-maybexs-perl
,libsys-mmap-perl [!hurd-any]
,liburi-encode-perl
,libwww-perl
,libwww-perl, liburi-perl
,libdata-dump-perl
,libdatetime-perl
,libclass-std-fast-perl
@ -74,7 +74,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
,libfile-slurp-perl
,mysql-client | mariadb-client | virtual-mysql-client
,perl-modules
,php5-mysql | php-mysql, php5-gd | php-gd , php5-apcu | php-apcu , php-apc | php-apcu-bc
,php5-mysql | php-mysql, php5-gd | php-gd , php5-apcu | php-apcu , php-apc | php-apcu-bc, php-json | php5-json
,policykit-1
,rsyslog | system-log-daemon
,zip

View File

@ -28,3 +28,4 @@ zmtelemetry\[[[:digit:]]+\]: INF \[Telemetry data uploaded successfully.\]$
zmtelemetry\[[[:digit:]]+\]: INF \[Sending data to ZoneMinder Telemetry server.\]$
zmtelemetry\[[[:digit:]]+\]: INF \[Collec?ting data to send to ZoneMinder Telemetry server.\]$
web_php\[[[:digit:]]+\]: INF \[Login successful for user "[[:alnum:]]+"\]$
zmeventnotification\[[[:digit:]]+\]: INF

View File

@ -1127,7 +1127,7 @@ our @options = (
},
{
name => 'ZM_LOG_LEVEL_FILE',
default => '-5',
default => '1',
description => 'Save logging output to component files',
help => q`
ZoneMinder logging is now more integrated between
@ -1312,7 +1312,7 @@ our @options = (
},
{
name => 'ZM_LOG_DEBUG_FILE',
default => '@ZM_LOGDIR@/zm_debug.log+',
default => '',
description => 'Where extra debug is output to',
help => q`
This option allows you to specify a different target for debug
@ -2468,7 +2468,7 @@ our @options = (
},
{
name => 'ZM_WATCH_MAX_DELAY',
default => '5',
default => '45',
description => 'The maximum delay allowed since the last captured image',
help => q`
The zmwatch daemon checks the image capture performance of the

View File

@ -1,6 +1,6 @@
# ==========================================================================
#
# ZoneMinder Acrest HTTP API Control Protocol Module, 20180214, Rev 3.0
# ZoneMinder Amcrest HTTP API Control Protocol Module, 20180214, Rev 3.0
#
# Change Log
#
@ -8,7 +8,7 @@
# - Fixes incorrect method names
# - Updates control sequences to Amcrest HTTP Protocol API v 2.12
# - Extends control features
#
#
# Rev 2.0:
# - Fixed installation instructions text, no changes to functionality.
#
@ -38,6 +38,7 @@ use Time::HiRes qw( usleep );
require ZoneMinder::Base;
require ZoneMinder::Control;
require LWP::UserAgent;
our @ISA = qw(ZoneMinder::Control);
@ -50,130 +51,109 @@ our @ISA = qw(ZoneMinder::Control);
use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all);
sub new
{
my $class = shift;
my $id = shift;
my $self = ZoneMinder::Control->new( $id );
bless( $self, $class );
srand( time() );
return $self;
sub new {
my $class = shift;
my $id = shift;
my $self = ZoneMinder::Control->new($id);
bless($self, $class);
return $self;
}
our $AUTOLOAD;
sub open {
my $self = shift;
sub AUTOLOAD
{
my $self = shift;
my $class = ref($self) || croak( "$self not object" );
my $name = $AUTOLOAD;
$name =~ s/.*://;
Debug( "Received command: $name" );
if ( exists($self->{$name}) )
{
return( $self->{$name} );
}
Fatal( "Can't access $name member of object of class $class" );
}
$self->loadMonitor();
my $username;
my $password;
my $realm = 'Login to ' . $self->{Monitor}->{ControlDevice};
sub open
{
my $self = shift;
if ( $self->{Monitor}->{ControlAddress} =~ /(.*):(.*)@(.*)/ ) {
$username = $1;
$password = $2;
$$self{address} = $3;
}
$self->loadMonitor();
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->credentials($$self{address}, $realm, $username, $password);
$self->{ua}->agent('ZoneMinder Control Agent/'.ZoneMinder::Base::ZM_VERSION);
# Detect REALM
my $res = $self->{ua}->get($$self{address}.'/cgi-bin/ptz.cgi');
if ( $res->is_success ) {
$self->{state} = 'open';
}
return;
}
sub initUA
{
my $self = shift;
my $user = undef;
my $password = undef;
my $address = undef;
if ( $res->status_line() eq '401 Unauthorized' ) {
if ( $self->{Monitor}->{ControlAddress} =~ /(.*):(.*)@(.*)/ )
{
$user = $1;
$password = $2;
$address = $3;
my $headers = $res->headers();
foreach my $k ( keys %$headers ) {
Debug("Initial Header $k => $$headers{$k}");
}
use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->credentials("$address", "Login to " . $self->{Monitor}->{ControlDevice}, "$user", "$password");
$self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
if ( $$headers{'www-authenticate'} ) {
my ( $auth, $tokens ) = $$headers{'www-authenticate'} =~ /^(\w+)\s+(.*)$/;
if ( $tokens =~ /\w+="([^"]+)"/i ) {
if ( $realm ne $1 ) {
$realm = $1;
Debug("Changing REALM to $realm");
$self->{ua}->credentials($$self{address}, $realm, $username, $password);
$res = $self->{ua}->get($$self{address}.'/cgi-bin/ptz.cgi');
if ( $res->is_success() ) {
$self->{state} = 'open';
return;
}
Error('Authentication still failed after updating REALM' . $res->status_line);
$headers = $res->headers();
foreach my $k ( keys %$headers ) {
Debug("Initial Header $k => $$headers{$k}");
} # end foreach
} else {
Error('Authentication failed, not a REALM problem');
}
} else {
Error('Failed to match realm in tokens');
} # end if
} else {
Debug('No headers line');
} # end if headers
} # end if $res->status_line() eq '401 Unauthorized'
$self->{state} = 'open';
}
sub destroyUA
{
my $self = shift;
$self->{ua} = undef;
sub close {
my $self = shift;
$self->{state} = 'closed';
}
sub close
{
my $self = shift;
$self->{state} = 'closed';
sub sendCmd {
my $self = shift;
my $cmd = shift;
my $result = undef;
$self->printMsg($cmd, 'Tx');
my $req = HTTP::Request->new( GET=>"http://$$self{address}/$cmd" );
my $res = $self->{ua}->request($req);
if ( $res->is_success ) {
$result = !undef;
# Command to camera appears successful, write Info item to log
Info('Camera control: \''.$res->status_line().'\' for URL '.$self->{Monitor}->{ControlAddress}.'/'.$cmd);
# TODO: Add code to retrieve $res->message_decode or some such. Then we could do things like check the camera status.
} else {
Error('Camera control command FAILED: \''.$res->status_line().'\' for URL '.$self->{Monitor}->{ControlAddress}.'/'.$cmd);
}
return $result;
}
sub printMsg
{
my $self = shift;
my $msg = shift;
my $msg_len = length($msg);
Debug( $msg."[".$msg_len."]" );
}
sub sendCmd
{
my $self = shift;
my $cmd = shift;
my $result = undef;
destroyUA($self);
initUA($self);
my $user = undef;
my $password = undef;
my $address = undef;
if ( $self->{Monitor}->{ControlAddress} =~ /(.*):(.*)@(.*)/ )
{
$user = $1;
$password = $2;
$address = $3;
}
printMsg( $cmd, "Tx" );
my $req = HTTP::Request->new( GET=>"http://$address/$cmd" );
my $res = $self->{ua}->request($req);
if ( $res->is_success )
{
$result = !undef;
# Command to camera appears successful, write Info item to log
Info( "Camera control: '".$res->status_line()."' for URL ".$self->{Monitor}->{ControlAddress}."/$cmd" );
# TODO: Add code to retrieve $res->message_decode or some such. Then we could do things like check the camera status.
}
else
{
Error( "Camera control command FAILED: '".$res->status_line()."' for URL ".$self->{Monitor}->{ControlAddress}."/$cmd" );
}
return( $result );
}
sub reset
{
my $self = shift;
# This reboots the camera effectively resetting it
Debug( "Camera Reset" );
$self->sendCmd( 'cgi-bin/magicBox.cgi?action=reboot' );
##FIXME: Exit is a bad idea as it appears to cause zmc to run away.
#Exit (0);
sub reset {
my $self = shift;
# This reboots the camera effectively resetting it
$self->sendCmd('cgi-bin/magicBox.cgi?action=reboot');
}
# NOTE: I'm putting this in, but absolute camera movement does not seem to be well supported in the classic skin ATM.
@ -184,163 +164,148 @@ sub reset
sub moveAbs ## Up, Down, Left, Right, etc. ??? Doesn't make sense here...
{
my $self = shift;
my $pan_degrees = shift || 0;
my $tilt_degrees = shift || 0;
my $speed = shift || 1;
Debug( "Move ABS" );
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1='.$pan_degrees.'&arg2='.$tilt_degrees.'&arg3=0&arg4='.$speed );
my $self = shift;
my $pan_degrees = shift || 0;
my $tilt_degrees = shift || 0;
my $speed = shift || 1;
Debug('Move ABS');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1='.$pan_degrees.'&arg2='.$tilt_degrees.'&arg3=0&arg4='.$speed);
}
sub moveConUp
{
my $self = shift;
Debug( "Move Up" );
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=Up&channel=0&arg1=0&arg2=1&arg3=0' );
usleep (500); ##XXX Should this be passed in as a "speed" parameter?
$self->sendCmd( 'cgi-bin/ptz.cgi?action=stop&code=Up&channel=0&arg1=0&arg2=1&arg3=0' );
sub moveConUp {
my $self = shift;
Debug('Move Up');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=Up&channel=0&arg1=0&arg2=1&arg3=0');
usleep(500); ##XXX Should this be passed in as a "speed" parameter?
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=Up&channel=0&arg1=0&arg2=1&arg3=0');
}
sub moveConDown
{
my $self = shift;
Debug( "Move Down" );
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=Down&channel=0&arg1=0&arg2=1&arg3=0' );
usleep (500);
$self->sendCmd( 'cgi-bin/ptz.cgi?action=stop&code=Down&channel=0&arg1=0&arg2=1&arg3=0' );
sub moveConDown {
my $self = shift;
Debug('Move Down');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=Down&channel=0&arg1=0&arg2=1&arg3=0');
usleep(500);
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=Down&channel=0&arg1=0&arg2=1&arg3=0');
}
sub moveConLeft
{
my $self = shift;
Debug( "Move Left" );
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=Left&channel=0&arg1=0&arg2=1&arg3=0' );
usleep (500);
$self->sendCmd( 'cgi-bin/ptz.cgi?action=stop&code=Left&channel=0&arg1=0&arg2=1&arg3=0' );
sub moveConLeft {
my $self = shift;
Debug('Move Left');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=Left&channel=0&arg1=0&arg2=1&arg3=0');
usleep(500);
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=Left&channel=0&arg1=0&arg2=1&arg3=0');
}
sub moveConRight
{
my $self = shift;
Debug( "Move Right" );
# $self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1=270&arg2=5&arg3=0' );
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=Right&channel=0&arg1=0&arg2=1&arg3=0' );
usleep (500);
Debug( "Move Right Stop" );
$self->sendCmd( 'cgi-bin/ptz.cgi?action=stop&code=Right&channel=0&arg1=0&arg2=1&arg3=0' );
sub moveConRight {
my $self = shift;
Debug('Move Right');
# $self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1=270&arg2=5&arg3=0' );
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=Right&channel=0&arg1=0&arg2=1&arg3=0');
usleep(500);
Debug('Move Right Stop');
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=Right&channel=0&arg1=0&arg2=1&arg3=0');
}
sub moveConUpRight
{
my $self = shift;
Debug( "Move Diagonally Up Right" );
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=RightUp&channel=0&arg1=1&arg2=1&arg3=0' );
usleep (500);
$self->sendCmd( 'cgi-bin/ptz.cgi?action=stop&code=RightUp&channel=0&arg1=0&arg2=1&arg3=0' );
sub moveConUpRight {
my $self = shift;
Debug('Move Diagonally Up Right');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=RightUp&channel=0&arg1=1&arg2=1&arg3=0');
usleep(500);
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=RightUp&channel=0&arg1=0&arg2=1&arg3=0');
}
sub moveConDownRight
{
my $self = shift;
Debug( "Move Diagonally Down Right" );
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=RightDown&channel=0&arg1=1&arg2=1&arg3=0' );
usleep (500);
$self->sendCmd( 'cgi-bin/ptz.cgi?action=stop&code=RightDown&channel=0&arg1=0&arg2=1&arg3=0' );
sub moveConDownRight {
my $self = shift;
Debug('Move Diagonally Down Right');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=RightDown&channel=0&arg1=1&arg2=1&arg3=0');
usleep(500);
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=RightDown&channel=0&arg1=0&arg2=1&arg3=0');
}
sub moveConUpLeft
{
my $self = shift;
Debug( "Move Diagonally Up Left" );
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=LeftUp&channel=0&arg1=1&arg2=1&arg3=0' );
usleep (500);
$self->sendCmd( 'cgi-bin/ptz.cgi?action=stop&code=LeftUp&channel=0&arg1=0&arg2=1&arg3=0' );
sub moveConUpLeft {
my $self = shift;
Debug('Move Diagonally Up Left');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=LeftUp&channel=0&arg1=1&arg2=1&arg3=0');
usleep(500);
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=LeftUp&channel=0&arg1=0&arg2=1&arg3=0');
}
sub moveConDownLeft
{
my $self = shift;
Debug( "Move Diagonally Down Left" );
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=LeftDown&channel=0&arg1=1&arg2=1&arg3=0' );
usleep (500);
$self->sendCmd( 'cgi-bin/ptz.cgi?action=stop&code=LeftDown&channel=0&arg1=0&arg2=1&arg3=0' );
sub moveConDownLeft {
my $self = shift;
Debug('Move Diagonally Down Left');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=LeftDown&channel=0&arg1=1&arg2=1&arg3=0');
usleep (500);
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=LeftDown&channel=0&arg1=0&arg2=1&arg3=0');
}
# Stop is not "correctly" implemented as control_functions.php translates this to "Center"
# So we'll just send the camera to 0* Horz, 0* Vert, zoom out; Also, Amcrest does not seem to
# support a generic stop-all-current-action command.
sub moveStop
{
my $self = shift;
Debug( "Move Stop/Center" );
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1=0&arg2=0&arg3=0&arg4=1' );
sub moveStop {
my $self = shift;
Debug('Move Stop/Center');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1=0&arg2=0&arg3=0&arg4=1');
}
# Move Camera to Home Position
# The current API does not support a Home per se, so we'll just send the camera to preset #1
# NOTE: It goes without saying that the user must have set up preset #1 for this to work.
sub presetHome
{
my $self = shift;
Debug( "Home Preset" );
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&channel=0&code=GotoPreset&&arg1=0&arg2=1&arg3=0&arg4=0' );
sub presetHome {
my $self = shift;
Debug('Home Preset');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&channel=0&code=GotoPreset&&arg1=0&arg2=1&arg3=0&arg4=0');
}
sub presetGoto
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Go To Preset $preset" );
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&channel=0&code=GotoPreset&&arg1=0&arg2='.$preset.'&arg3=0&arg4=0' );
sub presetGoto {
my $self = shift;
my $params = shift;
my $preset = $self->getParam($params, 'preset');
Debug("Go To Preset $preset");
$self->sendCmd('cgi-bin/ptz.cgi?action=start&channel=0&code=GotoPreset&&arg1=0&arg2='.$preset.'&arg3=0&arg4=0');
}
sub presetSet
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Set Preset" );
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&channel=0&code=SetPreset&arg1=0&arg2='.$preset.'&arg3=0&arg4=0' );
sub presetSet {
my $self = shift;
my $params = shift;
my $preset = $self->getParam($params, 'preset');
Debug('Set Preset');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&channel=0&code=SetPreset&arg1=0&arg2='.$preset.'&arg3=0&arg4=0');
}
# NOTE: This does not appear to be implemented in the classic skin. But we'll leave it here for later.
sub moveMap
{
my $self = shift;
my $params = shift;
sub moveMap {
my $self = shift;
my $params = shift;
my $xcoord = $self->getParam( $params, 'xcoord', $self->{Monitor}{Width}/2 );
my $ycoord = $self->getParam( $params, 'ycoord', $self->{Monitor}{Height}/2 );
# if the camera is mounted upside down, you may have to inverse these coordinates
# just use 360 minus pan instead of pan, 90 minus tilt instead of tilt
# Convert xcoord into pan position 0 to 359
my $pan = int(360 * $xcoord / $self->{Monitor}{Width});
# Convert ycoord into tilt position 0 to 89
my $tilt = 90 - int(90 * $ycoord / $self->{Monitor}{Height});
# Now get the following url:
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1='.$pan.'&arg2='.$tilt.'&arg3=1&arg4=1');
my $xcoord = $self->getParam( $params, 'xcoord', $self->{Monitor}{Width}/2 );
my $ycoord = $self->getParam( $params, 'ycoord', $self->{Monitor}{Height}/2 );
# if the camera is mounted upside down, you may have to inverse these coordinates
# just use 360 minus pan instead of pan, 90 minus tilt instead of tilt
# Convert xcoord into pan position 0 to 359
my $pan = int(360 * $xcoord / $self->{Monitor}{Width});
# Convert ycoord into tilt position 0 to 89
my $tilt = 90 - int(90 * $ycoord / $self->{Monitor}{Height});
# Now get the following url:
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1='.$pan.'&arg2='.$tilt.'&arg3=1&arg4=1');
}
sub zoomConTele
{
my $self = shift;
Debug( "Zoom continuous tele" );
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&channel=0&code=ZoomTele&arg1=0&arg2=0&arg3=0&arg4=0' );
usleep (100000);
$self->sendCmd( 'cgi-bin/ptz.cgi?action=stop&channel=0&code=ZoomTele&arg1=0&arg2=0&arg3=0&arg4=0' );
sub zoomConTele {
my $self = shift;
Debug('Zoom continuous tele');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&channel=0&code=ZoomTele&arg1=0&arg2=0&arg3=0&arg4=0');
usleep(100000);
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&channel=0&code=ZoomTele&arg1=0&arg2=0&arg3=0&arg4=0');
}
sub zoomConWide
{
my $self = shift;
Debug( "Zoom continuous wide" );
$self->sendCmd( 'cgi-bin/ptz.cgi?action=start&channel=0&code=ZoomWide&arg1=0&arg2=0&arg3=0&arg4=0' );
usleep (100000);
$self->sendCmd( 'cgi-bin/ptz.cgi?action=stop&channel=0&code=ZoomWide&arg1=0&arg2=0&arg3=0&arg4=0' );
sub zoomConWide {
my $self = shift;
Debug('Zoom continuous wide');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&channel=0&code=ZoomWide&arg1=0&arg2=0&arg3=0&arg4=0');
usleep (100000);
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&channel=0&code=ZoomWide&arg1=0&arg2=0&arg3=0&arg4=0');
}
1;
@ -355,7 +320,7 @@ ZoneMinder::Control::Amcrest_HTTP - Amcrest camera control
=head1 DESCRIPTION
This module contains the implementation of the Amcrest Camera
This module contains the implementation of the Amcrest Camera
controllable SDK API.
NOTE: This module implements interaction with the camera in clear text.

View File

@ -1,6 +1,6 @@
# ==========================================================================
#
# ZoneMinder Axis version 2 API Control Protocol Module, $Date$, $Revision$
# ZoneMinder Axis version 2 API Control Protocol Module
# Copyright (C) 2001-2008 Philip Coombes
#
# This program is free software; you can redistribute it and/or
@ -43,349 +43,359 @@ use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep );
use URI;
sub open
{
my $self = shift;
our $ADDRESS;
$self->loadMonitor();
sub open {
my $self = shift;
use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
$self->loadMonitor();
if ( $self->{Monitor}->{ControlAddress} !~ /^\w+:\/\// ) {
# Has no scheme at the beginning, so won't parse as a URI
$self->{Monitor}->{ControlAddress} = 'http://'.$self->{Monitor}->{ControlAddress};
}
my $uri = URI->new($self->{Monitor}->{ControlAddress});
$ADDRESS = $uri->scheme.'://'.$uri->authority().$uri->path().($uri->port()?':'.$uri->port():'');
use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->cookie_jar( {} );
$self->{ua}->agent('ZoneMinder Control Agent/'.ZoneMinder::Base::ZM_VERSION);
$self->{state} = 'closed';
my ( $username, $password, $host ) = ( $uri->authority() =~ /^([^:]+):([^@]*)@(.+)$/ );
my $realm = $self->{Monitor}->{ControlDevice};
$self->{ua}->credentials($ADDRESS, $realm, $username, $password);
# test auth
my $res = $self->{ua}->get($ADDRESS.'/cgi/ptdc.cgi');
if ( $res->is_success ) {
$self->{state} = 'open';
}
return;
}
sub printMsg
{
my $self = shift;
my $msg = shift;
my $msg_len = length($msg);
if ( $res->status_line() eq '401 Unauthorized' ) {
Debug( $msg."[".$msg_len."]" );
}
sub sendCmd
{
my $self = shift;
my $cmd = shift;
my $result = undef;
printMsg( $cmd, "Tx" );
#print( "http://$address/$cmd\n" );
my $req = HTTP::Request->new( GET=>"http://".$self->{Monitor}->{ControlAddress}."/$cmd" );
my $res = $self->{ua}->request($req);
if ( $res->is_success )
{
$result = !undef;
}
else
{
Error( "Error check failed: '".$res->status_line()."'" );
my $headers = $res->headers();
foreach my $k ( keys %$headers ) {
Debug("Initial Header $k => $$headers{$k}");
}
return( $result );
if ( $$headers{'www-authenticate'} ) {
Debug('Authenticating');
my ( $auth, $tokens ) = $$headers{'www-authenticate'} =~ /^(\w+)\s+(.*)$/;
if ( $tokens =~ /\w+="([^"]+)"/i ) {
if ( $realm ne $1 ) {
$realm = $1;
Debug("Changing REALM to $realm");
$self->{ua}->credentials($host, $realm, $username, $password);
$res = $self->{ua}->get($ADDRESS);
if ( $res->is_success() ) {
$self->{state} = 'open';
return;
}
Error('Authentication still failed after updating REALM'.$res->status_line);
$headers = $res->headers();
foreach my $k ( keys %$headers ) {
Debug("Initial Header $k => $$headers{$k}");
} # end foreach
} else {
Error('Authentication failed, not a REALM problem');
}
} else {
Error('Failed to match realm in tokens');
} # end if
} else {
Debug('No headers line');
} # end if headers
} # end if $res->status_line() eq '401 Unauthorized'
} # end sub open
sub sendCmd {
my $self = shift;
my $cmd = shift;
$self->printMsg($cmd, 'Tx');
my $url = $ADDRESS.$cmd;
my $res = $self->{ua}->get($url);
if ( $res->is_success ) {
Debug('sndCmd command: ' . $url . ' content: '.$res->content);
return !undef;
}
Error("Error cmd $url failed: '".$res->status_line()."'");
return undef;
}
sub cameraReset
{
my $self = shift;
Debug( "Camera Reset" );
my $cmd = "/axis-cgi/admin/restart.cgi";
$self->sendCmd( $cmd );
sub cameraReset {
my $self = shift;
Debug('Camera Reset');
my $cmd = '/axis-cgi/admin/restart.cgi';
$self->sendCmd($cmd);
}
sub moveConUp
{
my $self = shift;
Debug( "Move Up" );
my $cmd = "/axis-cgi/com/ptz.cgi?move=up";
$self->sendCmd( $cmd );
sub moveConUp {
my $self = shift;
Debug('Move Up');
my $cmd = '/axis-cgi/com/ptz.cgi?move=up';
$self->sendCmd($cmd);
}
sub moveConDown
{
my $self = shift;
Debug( "Move Down" );
my $cmd = "/axis-cgi/com/ptz.cgi?move=down";
$self->sendCmd( $cmd );
sub moveConDown {
my $self = shift;
Debug('Move Down');
my $cmd = '/axis-cgi/com/ptz.cgi?move=down';
$self->sendCmd($cmd);
}
sub moveConLeft
{
my $self = shift;
Debug( "Move Left" );
my $cmd = "/axis-cgi/com/ptz.cgi?move=left";
$self->sendCmd( $cmd );
sub moveConLeft {
my $self = shift;
Debug('Move Left');
my $cmd = '/axis-cgi/com/ptz.cgi?move=left';
$self->sendCmd($cmd);
}
sub moveConRight
{
my $self = shift;
Debug( "Move Right" );
my $cmd = "/axis-cgi/com/ptz.cgi?move=right";
$self->sendCmd( $cmd );
sub moveConRight {
my $self = shift;
Debug('Move Right');
my $cmd = '/axis-cgi/com/ptz.cgi?move=right';
$self->sendCmd($cmd);
}
sub moveConUpRight
{
my $self = shift;
Debug( "Move Up/Right" );
my $cmd = "/axis-cgi/com/ptz.cgi?move=upright";
$self->sendCmd( $cmd );
sub moveConUpRight {
my $self = shift;
Debug('Move Up/Right');
my $cmd = '/axis-cgi/com/ptz.cgi?move=upright';
$self->sendCmd($cmd);
}
sub moveConUpLeft
{
my $self = shift;
Debug( "Move Up/Left" );
my $cmd = "/axis-cgi/com/ptz.cgi?move=upleft";
$self->sendCmd( $cmd );
sub moveConUpLeft {
my $self = shift;
Debug('Move Up/Left');
my $cmd = '/axis-cgi/com/ptz.cgi?move=upleft';
$self->sendCmd($cmd);
}
sub moveConDownRight
{
my $self = shift;
Debug( "Move Down/Right" );
my $cmd = "/axis-cgi/com/ptz.cgi?move=downright";
$self->sendCmd( $cmd );
sub moveConDownRight {
my $self = shift;
Debug('Move Down/Right');
my $cmd = '/axis-cgi/com/ptz.cgi?move=downright';
$self->sendCmd( $cmd );
}
sub moveConDownLeft
{
my $self = shift;
Debug( "Move Down/Left" );
my $cmd = "/axis-cgi/com/ptz.cgi?move=downleft";
$self->sendCmd( $cmd );
sub moveConDownLeft {
my $self = shift;
Debug('Move Down/Left');
my $cmd = '/axis-cgi/com/ptz.cgi?move=downleft';
$self->sendCmd($cmd);
}
sub moveMap
{
my $self = shift;
my $params = shift;
my $xcoord = $self->getParam( $params, 'xcoord' );
my $ycoord = $self->getParam( $params, 'ycoord' );
Debug( "Move Map to $xcoord,$ycoord" );
my $cmd = "/axis-cgi/com/ptz.cgi?center=$xcoord,$ycoord&imagewidth=".$self->{Monitor}->{Width}."&imageheight=".$self->{Monitor}->{Height};
$self->sendCmd( $cmd );
sub moveMap {
my $self = shift;
my $params = shift;
my $xcoord = $self->getParam($params, 'xcoord');
my $ycoord = $self->getParam($params, 'ycoord');
Debug("Move Map to $xcoord,$ycoord");
my $cmd = "/axis-cgi/com/ptz.cgi?center=$xcoord,$ycoord&imagewidth=".$self->{Monitor}->{Width}.'&imageheight='.$self->{Monitor}->{Height};
$self->sendCmd($cmd);
}
sub moveRelUp
{
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'tiltstep' );
Debug( "Step Up $step" );
my $cmd = "/axis-cgi/com/ptz.cgi?rtilt=$step";
$self->sendCmd( $cmd );
sub moveRelUp {
my $self = shift;
my $params = shift;
my $step = $self->getParam($params, 'tiltstep');
Debug("Step Up $step");
my $cmd = '/axis-cgi/com/ptz.cgi?rtilt='.$step;
$self->sendCmd($cmd);
}
sub moveRelDown
{
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'tiltstep' );
Debug( "Step Down $step" );
my $cmd = "/axis-cgi/com/ptz.cgi?rtilt=-$step";
$self->sendCmd( $cmd );
sub moveRelDown {
my $self = shift;
my $params = shift;
my $step = $self->getParam($params, 'tiltstep');
Debug("Step Down $step");
my $cmd = '/axis-cgi/com/ptz.cgi?rtilt=-'.$step;
$self->sendCmd($cmd);
}
sub moveRelLeft
{
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'panstep' );
Debug( "Step Left $step" );
my $cmd = "/axis-cgi/com/ptz.cgi?rpan=-$step";
$self->sendCmd( $cmd );
sub moveRelLeft {
my $self = shift;
my $params = shift;
my $step = $self->getParam($params, 'panstep');
Debug("Step Left $step");
my $cmd = '/axis-cgi/com/ptz.cgi?rpan=-'.$step;
$self->sendCmd($cmd);
}
sub moveRelRight
{
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'panstep' );
Debug( "Step Right $step" );
my $cmd = "/axis-cgi/com/ptz.cgi?rpan=$step";
$self->sendCmd( $cmd );
sub moveRelRight {
my $self = shift;
my $params = shift;
my $step = $self->getParam($params, 'panstep');
Debug("Step Right $step");
my $cmd = '/axis-cgi/com/ptz.cgi?rpan='.$step;
$self->sendCmd($cmd);
}
sub moveRelUpRight
{
my $self = shift;
my $params = shift;
my $panstep = $self->getParam( $params, 'panstep' );
my $tiltstep = $self->getParam( $params, 'tiltstep' );
Debug( "Step Up/Right $tiltstep/$panstep" );
my $cmd = "/axis-cgi/com/ptz.cgi?rpan=$panstep&rtilt=$tiltstep";
$self->sendCmd( $cmd );
sub moveRelUpRight {
my $self = shift;
my $params = shift;
my $panstep = $self->getParam($params, 'panstep');
my $tiltstep = $self->getParam($params, 'tiltstep');
Debug("Step Up/Right $tiltstep/$panstep");
my $cmd = "/axis-cgi/com/ptz.cgi?rpan=$panstep&rtilt=$tiltstep";
$self->sendCmd($cmd);
}
sub moveRelUpLeft
{
my $self = shift;
my $params = shift;
my $panstep = $self->getParam( $params, 'panstep' );
my $tiltstep = $self->getParam( $params, 'tiltstep' );
Debug( "Step Up/Left $tiltstep/$panstep" );
my $cmd = "/axis-cgi/com/ptz.cgi?rpan=-$panstep&rtilt=$tiltstep";
$self->sendCmd( $cmd );
sub moveRelUpLeft {
my $self = shift;
my $params = shift;
my $panstep = $self->getParam($params, 'panstep');
my $tiltstep = $self->getParam($params, 'tiltstep');
Debug("Step Up/Left $tiltstep/$panstep");
my $cmd = "/axis-cgi/com/ptz.cgi?rpan=-$panstep&rtilt=$tiltstep";
$self->sendCmd($cmd);
}
sub moveRelDownRight
{
my $self = shift;
my $params = shift;
my $panstep = $self->getParam( $params, 'panstep' );
my $tiltstep = $self->getParam( $params, 'tiltstep' );
Debug( "Step Down/Right $tiltstep/$panstep" );
my $cmd = "/axis-cgi/com/ptz.cgi?rpan=$panstep&rtilt=-$tiltstep";
$self->sendCmd( $cmd );
sub moveRelDownRight {
my $self = shift;
my $params = shift;
my $panstep = $self->getParam($params, 'panstep');
my $tiltstep = $self->getParam($params, 'tiltstep');
Debug("Step Down/Right $tiltstep/$panstep");
my $cmd = "/axis-cgi/com/ptz.cgi?rpan=$panstep&rtilt=-$tiltstep";
$self->sendCmd($cmd);
}
sub moveRelDownLeft
{
my $self = shift;
my $params = shift;
my $panstep = $self->getParam( $params, 'panstep' );
my $tiltstep = $self->getParam( $params, 'tiltstep' );
Debug( "Step Down/Left $tiltstep/$panstep" );
my $cmd = "/axis-cgi/com/ptz.cgi?rpan=-$panstep&rtilt=-$tiltstep";
$self->sendCmd( $cmd );
sub moveRelDownLeft {
my $self = shift;
my $params = shift;
my $panstep = $self->getParam($params, 'panstep');
my $tiltstep = $self->getParam($params, 'tiltstep');
Debug("Step Down/Left $tiltstep/$panstep");
my $cmd = "/axis-cgi/com/ptz.cgi?rpan=-$panstep&rtilt=-$tiltstep";
$self->sendCmd($cmd);
}
sub zoomRelTele
{
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'step' );
Debug( "Zoom Tele" );
my $cmd = "/axis-cgi/com/ptz.cgi?rzoom=$step";
$self->sendCmd( $cmd );
sub zoomRelTele {
my $self = shift;
my $params = shift;
my $step = $self->getParam($params, 'step');
Debug('Zoom Tele');
my $cmd = "/axis-cgi/com/ptz.cgi?rzoom=$step";
$self->sendCmd($cmd);
}
sub zoomRelWide
{
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'step' );
Debug( "Zoom Wide" );
my $cmd = "/axis-cgi/com/ptz.cgi?rzoom=-$step";
$self->sendCmd( $cmd );
sub zoomRelWide {
my $self = shift;
my $params = shift;
my $step = $self->getParam($params, 'step');
Debug('Zoom Wide');
my $cmd = "/axis-cgi/com/ptz.cgi?rzoom=-$step";
$self->sendCmd($cmd);
}
sub focusRelNear
{
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'step' );
Debug( "Focus Near" );
my $cmd = "/axis-cgi/com/ptz.cgi?rfocus=-$step";
$self->sendCmd( $cmd );
sub focusRelNear {
my $self = shift;
my $params = shift;
my $step = $self->getParam($params, 'step');
Debug('Focus Near');
my $cmd = "/axis-cgi/com/ptz.cgi?rfocus=-$step";
$self->sendCmd($cmd);
}
sub focusRelFar
{
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'step' );
Debug( "Focus Far" );
my $cmd = "/axis-cgi/com/ptz.cgi?rfocus=$step";
$self->sendCmd( $cmd );
sub focusRelFar {
my $self = shift;
my $params = shift;
my $step = $self->getParam($params, 'step');
Debug('Focus Far');
my $cmd = "/axis-cgi/com/ptz.cgi?rfocus=$step";
$self->sendCmd($cmd);
}
sub focusAuto
{
my $self = shift;
Debug( "Focus Auto" );
my $cmd = "/axis-cgi/com/ptz.cgi?autofocus=on";
$self->sendCmd( $cmd );
sub focusAuto {
my $self = shift;
Debug('Focus Auto');
my $cmd = '/axis-cgi/com/ptz.cgi?autofocus=on';
$self->sendCmd($cmd);
}
sub focusMan
{
my $self = shift;
Debug( "Focus Manual" );
my $cmd = "/axis-cgi/com/ptz.cgi?autofocus=off";
$self->sendCmd( $cmd );
sub focusMan {
my $self = shift;
Debug('Focus Manual');
my $cmd = '/axis-cgi/com/ptz.cgi?autofocus=off';
$self->sendCmd($cmd);
}
sub irisRelOpen
{
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'step' );
Debug( "Iris Open" );
my $cmd = "/axis-cgi/com/ptz.cgi?riris=$step";
$self->sendCmd( $cmd );
sub irisRelOpen {
my $self = shift;
my $params = shift;
my $step = $self->getParam($params, 'step');
Debug('Iris Open');
my $cmd = "/axis-cgi/com/ptz.cgi?riris=$step";
$self->sendCmd($cmd);
}
sub irisRelClose
{
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'step' );
Debug( "Iris Close" );
my $cmd = "/axis-cgi/com/ptz.cgi?riris=-$step";
$self->sendCmd( $cmd );
sub irisRelClose {
my $self = shift;
my $params = shift;
my $step = $self->getParam($params, 'step');
Debug('Iris Close');
my $cmd = "/axis-cgi/com/ptz.cgi?riris=-$step";
$self->sendCmd($cmd);
}
sub irisAuto
{
my $self = shift;
Debug( "Iris Auto" );
my $cmd = "/axis-cgi/com/ptz.cgi?autoiris=on";
$self->sendCmd( $cmd );
sub irisAuto {
my $self = shift;
Debug('Iris Auto');
my $cmd = '/axis-cgi/com/ptz.cgi?autoiris=on';
$self->sendCmd($cmd);
}
sub irisMan
{
my $self = shift;
Debug( "Iris Manual" );
my $cmd = "/axis-cgi/com/ptz.cgi?autoiris=off";
$self->sendCmd( $cmd );
sub irisMan {
my $self = shift;
Debug('Iris Manual');
my $cmd = '/axis-cgi/com/ptz.cgi?autoiris=off';
$self->sendCmd($cmd);
}
sub presetClear
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Clear Preset $preset" );
my $cmd = "/axis-cgi/com/ptz.cgi?removeserverpresetno=$preset";
$self->sendCmd( $cmd );
sub presetClear {
my $self = shift;
my $params = shift;
my $preset = $self->getParam($params, 'preset');
Debug("Clear Preset $preset");
my $cmd = "/axis-cgi/com/ptz.cgi?removeserverpresetno=$preset";
$self->sendCmd($cmd);
}
sub presetSet
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Set Preset $preset" );
my $cmd = "/axis-cgi/com/ptz.cgi?setserverpresetno=$preset";
$self->sendCmd( $cmd );
sub presetSet {
my $self = shift;
my $params = shift;
my $preset = $self->getParam($params, 'preset');
Debug("Set Preset $preset");
my $cmd = "/axis-cgi/com/ptz.cgi?setserverpresetno=$preset";
$self->sendCmd($cmd);
}
sub presetGoto
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Goto Preset $preset" );
my $cmd = "/axis-cgi/com/ptz.cgi?gotoserverpresetno=$preset";
$self->sendCmd( $cmd );
sub presetGoto {
my $self = shift;
my $params = shift;
my $preset = $self->getParam($params, 'preset');
Debug("Goto Preset $preset");
my $cmd = "/axis-cgi/com/ptz.cgi?gotoserverpresetno=$preset";
$self->sendCmd($cmd);
}
sub presetHome
{
my $self = shift;
Debug( "Home Preset" );
my $cmd = "/axis-cgi/com/ptz.cgi?move=home";
$self->sendCmd( $cmd );
sub presetHome {
my $self = shift;
Debug('Home Preset');
my $cmd = '/axis-cgi/com/ptz.cgi?move=home';
$self->sendCmd($cmd);
}
1;

View File

@ -1,6 +1,6 @@
# ==========================================================================
#
# ZoneMinder Airlink SkyIPCam AICN747/AICN747W Control Protocol Module, $Date: 2008-09-13 17:30:29 +0000 (Sat, 13 Sept 2008) $, $Revision: 2229 $
# ZoneMinder Airlink SkyIPCam AICN747/AICN747W Control Protocol Module
# Copyright (C) 2008 Brian Rudy (brudyNO@SPAMpraecogito.com)
#
# This program is free software; you can redistribute it and/or
@ -43,8 +43,6 @@ our @ISA = qw(ZoneMinder::Control);
use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep );
sub open {
my $self = shift;
@ -52,58 +50,50 @@ sub open {
use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
$self->{ua}->agent('ZoneMinder Control Agent/'.ZoneMinder::Base::ZM_VERSION);
$self->{state} = 'open';
}
sub printMsg {
my $self = shift;
my $msg = shift;
my $msg_len = length($msg);
Debug( $msg."[".$msg_len."]" );
}
sub sendCmd {
my $self = shift;
my $cmd = shift;
my $result = undef;
printMsg( $cmd, "Tx" );
$self->printMsg($cmd, 'Tx');
my $url;
if ( $self->{Monitor}->{ControlAddress} =~ /^http/ ) {
if ( $self->{Monitor}->{ControlAddress} =~ /^http/i ) {
$url = $self->{Monitor}->{ControlAddress}.$cmd;
} else {
$url = 'http://'.$self->{Monitor}->{ControlAddress}.$cmd;
} # en dif
my $req = HTTP::Request->new( GET=>$url );
} # end if
my $req = HTTP::Request->new(GET=>$url);
my $res = $self->{ua}->request($req);
if ( $res->is_success ) {
$result = !undef;
} else {
Error( "Error check failed: '".$res->status_line()."'" );
Error('Error check failed: \''.$res->status_line().'\'');
}
return( $result );
return $result;
}
sub reset {
my $self = shift;
Debug( "Camera Reset" );
my $cmd = "/admin/ptctl.cgi?move=reset";
$self->sendCmd( $cmd );
Debug('Camera Reset');
my $cmd = '/admin/ptctl.cgi?move=reset';
$self->sendCmd($cmd);
}
sub moveMap {
my $self = shift;
my $params = shift;
my $xcoord = $self->getParam( $params, 'xcoord' );
my $ycoord = $self->getParam( $params, 'ycoord' );
my $xcoord = $self->getParam($params, 'xcoord');
my $ycoord = $self->getParam($params, 'ycoord');
my $hor = $xcoord * 100 / $self->{Monitor}->{Width};
my $ver = $ycoord * 100 / $self->{Monitor}->{Height};
@ -125,81 +115,81 @@ sub moveMap {
elsif ( $hor > 50 ) {
# right
$horSteps = (($hor - 50) / 50) * $maxhor;
$horDir = "right";
$horDir = 'right';
}
# Vertical movement
if ( $ver < 50 ) {
# up
$verSteps = ((50 - $ver) / 50) * $maxver;
$verDir = "up";
$verDir = 'up';
}
elsif ( $ver > 50 ) {
# down
$verSteps = (($ver - 50) / 50) * $maxver;
$verDir = "down";
$verDir = 'down';
}
my $v = int($verSteps);
my $h = int($horSteps);
Debug( "Move Map to $xcoord,$ycoord, hor=$h $horDir, ver=$v $verDir");
Debug("Move Map to $xcoord,$ycoord, hor=$h $horDir, ver=$v $verDir");
my $cmd = "/cgi/admin/ptctrl.cgi?action=movedegree&Cmd=$horDir&Degree=$h";
$self->sendCmd( $cmd );
$self->sendCmd($cmd);
$cmd = "/cgi/admin/ptctrl.cgi?action=movedegree&Cmd=$verDir&Degree=$v";
$self->sendCmd( $cmd );
$self->sendCmd($cmd);
}
sub moveRelUp {
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'tiltstep' );
Debug( "Step Up $step" );
my $cmd = "/admin/ptctl.cgi?move=up";
$self->sendCmd( $cmd );
my $step = $self->getParam($params, 'tiltstep');
Debug("Step Up $step");
my $cmd = '/admin/ptctl.cgi?move=up';
$self->sendCmd($cmd);
}
sub moveRelDown {
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'tiltstep' );
Debug( "Step Down $step" );
my $cmd = "/admin/ptctl.cgi?move=down";
$self->sendCmd( $cmd );
my $step = $self->getParam($params, 'tiltstep');
Debug("Step Down $step");
my $cmd = '/admin/ptctl.cgi?move=down';
$self->sendCmd($cmd);
}
sub moveRelLeft {
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'panstep' );
my $step = $self->getParam($params, 'panstep');
if ( $self->{Monitor}->{Orientation} eq "hori" ) {
Debug( "Stepping Right because flipped horizontally " );
$self->sendCmd( "/admin/ptctl.cgi?move=right" );
if ( $self->{Monitor}->{Orientation} eq 'FLIP_HORI' ) {
Debug('Stepping Right because flipped horizontally');
$self->sendCmd('/admin/ptctl.cgi?move=right');
} else {
Debug( "Step Left" );
$self->sendCmd( "/admin/ptctl.cgi?move=left" );
Debug('Step Left');
$self->sendCmd('/admin/ptctl.cgi?move=left');
}
}
sub moveRelRight {
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'panstep' );
if ( $self->{Monitor}->{Orientation} eq "hori" ) {
Debug( "Stepping Left because flipped horizontally " );
$self->sendCmd( "/admin/ptctl.cgi?move=left" );
my $step = $self->getParam($params, 'panstep');
if ( $self->{Monitor}->{Orientation} eq 'FLIP_HORI' ) {
Debug('Stepping Left because flipped horizontally');
$self->sendCmd('/admin/ptctl.cgi?move=left');
} else {
Debug( "Step Right" );
$self->sendCmd( "/admin/ptctl.cgi?move=right" );
Debug('Step Right');
$self->sendCmd('/admin/ptctl.cgi?move=right');
}
}
sub presetClear {
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Clear Preset $preset" );
my $preset = $self->getParam($params, 'preset');
Debug("Clear Preset $preset");
#my $cmd = "/axis-cgi/com/ptz.cgi?removeserverpresetno=$preset";
#$self->sendCmd( $cmd );
}
@ -207,26 +197,26 @@ sub presetClear {
sub presetSet {
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Set Preset $preset" );
my $cmd = "/admin/ptctl.cgi?position=" . ($preset - 1) . "&positionname=zm$preset";
my $preset = $self->getParam($params, 'preset');
Debug("Set Preset $preset");
my $cmd = '/admin/ptctl.cgi?position=' . ($preset - 1) . "&positionname=zm$preset";
$self->sendCmd( $cmd );
}
sub presetGoto {
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Goto Preset $preset" );
my $cmd = "/admin/ptctl.cgi?move=p" . ($preset - 1);
$self->sendCmd( $cmd );
my $preset = $self->getParam($params, 'preset');
Debug("Goto Preset $preset");
my $cmd = '/admin/ptctl.cgi?move=p'.($preset - 1);
$self->sendCmd($cmd);
}
sub presetHome {
my $self = shift;
Debug( "Home Preset" );
my $cmd = "/admin/ptctl.cgi?move=h";
$self->sendCmd( $cmd );
Debug('Home Preset');
my $cmd = '/admin/ptctl.cgi?move=h';
$self->sendCmd($cmd);
}
1;

View File

@ -36,9 +36,172 @@ require ZoneMinder::Server;
#our @ISA = qw(Exporter ZoneMinder::Base);
use parent qw(ZoneMinder::Object);
use vars qw/ $table $primary_key /;
use vars qw/ $table $primary_key %fields $serial %defaults $debug/;
$table = 'Monitors';
$primary_key = 'Id';
$serial = $primary_key = 'Id';
%fields = map { $_ => $_ } qw(
Id
Name
Notes
ServerId
StorageId
Type
Function
Enabled
LinkedMonitors
Triggers
Device
Channel
Format
V4LMultiBuffer
V4LCapturesPerFrame
Protocol
Method
Host
Port
SubPath
Path
Options
User
Pass
Width
Height
Colours
Palette
Orientation
Deinterlacing
DecoderHWAccelName
DecoderHWAccelDevice
SaveJPEGs
VideoWriter
OutputCodec
OutputContainer
EncoderParameters
RecordAudio
RTSPDescribe
Brightness
Contrast
Hue
Colour
EventPrefix
LabelFormat
LabelX
LabelY
LabelSize
ImageBufferCount
WarmupCount
PreEventCount
PostEventCount
StreamReplayBuffer
AlarmFrameCount
SectionLength
MinSectionLength
FrameSkip
MotionFrameSkip
AnalysisFPSLimit
AnalysisUpdateDelay
MaxFPS
AlarmMaxFPS
FPSReportInterval
RefBlendPerc
AlarmRefBlendPerc
Controllable
ControlId
ControlDevice
ControlAddress
AutoStopTimeout
TrackMotion
TrackDelay
ReturnLocation
ReturnDelay
DefaultRate
DefaultScale
SignalCheckPoints
SignalCheckColour
WebColour
Exif
Sequence
);
%defaults = (
ServerId => 0,
StorageId => 0,
Type => 'Ffmpeg',
Function => 'Mocord',
Enabled => 1,
LinkedMonitors => undef,
Device => '',
Channel => 0,
Format => 0,
V4LMultiBuffer => undef,
V4LCapturesPerFrame => 1,
Protocol => undef,
Method => '',
Host => undef,
Port => '',
SubPath => '',
Path => undef,
Options => undef,
User => undef,
Pass => undef,
Width => undef,
Height => undef,
Colours => 4,
Palette => 0,
Orientation => undef,
Deinterlacing => 0,
DecoderHWAccelName => undef,
DecoderHWAccelDevice => undef,
SaveJPEGs => 3,
VideoWriter => 0,
OutputCodec => undef,
OutputContainer => undef,
EncoderParameters => "# Lines beginning with # are a comment \n# For changing quality, use the crf option\n# 1 is best, 51 is worst quality\n#crf=23\n",
RecordAudio=>0,
RTSPDescribe=>0,
Brightness => -1,
Contrast => -1,
Hue => -1,
Colour => -1,
EventPrefix => 'Event-',
LabelFormat => '%N - %d/%m/%y %H:%M:%S',
LabelX => 0,
LabelY => 0,
LabelSize => 1,
ImageBufferCount => 20,
WarmupCount => 0,
PreEventCount => 5,
PostEventCount => 5,
StreamReplayBuffer => 0,
AlarmFrameCount => 1,
SectionLength => 600,
MinSectionLength => 10,
FrameSkip => 0,
MotionFrameSkip => 0,
AnalysisFPSLimit => undef,
AnalysisUpdateDelay => 0,
MaxFPS => undef,
AlarmMaxFPS => undef,
FPSReportInterval => 100,
RefBlendPerc => 6,
AlarmRefBlendPerc => 6,
Controllable => 0,
ControlId => undef,
ControlDevice => undef,
ControlAddress => undef,
AutoStopTimeout => undef,
TrackMotion => 0,
TrackDelay => undef,
ReturnLocation => -1,
ReturnDelay => undef,
DefaultRate => 100,
DefaultScale => 100,
SignalCheckPoints => 0,
SignalCheckColour => '#0000BE',
WebColour => '#ff0000',
Exif => 0,
Sequence => undef,
);
sub Server {
return new ZoneMinder::Server( $_[0]{ServerId} );

View File

@ -108,6 +108,9 @@ if ( $options{command} ) {
Fatal("Unable to load control data for monitor $id");
}
my $protocol = $monitor->{Protocol};
if ( !$protocol ) {
Fatal('No protocol is set in monitor. Please edit the monitor, edit control type, select the control capability and fill in the Protocol field');
}
if ( -x $protocol ) {
# Protocol is actually a script!

View File

@ -23,6 +23,7 @@
use strict;
use bytes;
use utf8;
@EXTRA_PERL_LIB@
use ZoneMinder;
@ -34,6 +35,7 @@ use Sys::MemInfo qw(totalmem);
use Sys::CPU qw(cpu_count);
use POSIX qw(strftime uname);
use JSON::MaybeXS;
use Encode;
$ENV{PATH} = '/bin:/usr/bin:/usr/local/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
@ -166,7 +168,7 @@ sub sendData {
$req->header('content-length' => length($msg));
$req->header('connection' => 'Close');
$req->content($msg);
$req->content(encode('UTF-8',$msg));
my $resp = $ua->request($req);
my $resp_msg = $resp->decoded_content;

View File

@ -329,14 +329,13 @@ sub loadMonitor {
} # end sub loadMonitor
sub loadMonitors {
Debug('Loading monitors');
$monitor_reload_time = time();
my %new_monitors = ();
my $sql = q`SELECT * FROM Monitors
WHERE find_in_set( Function, 'Modect,Mocord,Nodect' )`.
( $Config{ZM_SERVER_ID} ? ' AND ServerId=?' : '' )
my $sql = 'SELECT * FROM `Monitors`
WHERE find_in_set( `Function`, \'Modect,Mocord,Nodect\' )'.
( $Config{ZM_SERVER_ID} ? ' AND `ServerId`=?' : '' )
;
my $sth = $dbh->prepare_cached( $sql )
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );

View File

@ -81,7 +81,7 @@ void FFMPEGInit() {
av_log_set_callback(log_libav_callback);
Info("Enabling ffmpeg logs, as LOG_DEBUG+LOG_FFMPEG are enabled in options");
} else {
Info("Not enabling ffmpeg logs, as LOG_FFMPEG and/or LOG_DEBUG is disabled in options, or this monitor not part of your debug targets");
Info("Not enabling ffmpeg logs, as LOG_FFMPEG and/or LOG_DEBUG is disabled in options, or this monitor is not part of your debug targets");
av_log_set_level(AV_LOG_QUIET);
}
#if !LIBAVFORMAT_VERSION_CHECK(58, 9, 0, 64, 0)
@ -291,17 +291,18 @@ static void zm_log_fps(double d, const char *postfix) {
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
void zm_dump_codecpar ( const AVCodecParameters *par ) {
Debug(1, "Dumping codecpar codec_type(%d) codec_id(%d %s) codec_tag(%d) width(%d) height(%d) bit_rate(%d) format(%d = %s)",
par->codec_type,
par->codec_id,
avcodec_get_name(par->codec_id),
par->codec_tag,
par->width,
par->height,
par->bit_rate,
par->format,
((AVPixelFormat)par->format == AV_PIX_FMT_NONE ? "none" : av_get_pix_fmt_name((AVPixelFormat)par->format))
);
Debug(1, "Dumping codecpar codec_type(%d %s) codec_id(%d %s) codec_tag(%" PRIu32 ") width(%d) height(%d) bit_rate(%" PRIu64 ") format(%d %s)",
par->codec_type,
av_get_media_type_string(par->codec_type),
par->codec_id,
avcodec_get_name(par->codec_id),
par->codec_tag,
par->width,
par->height,
par->bit_rate,
par->format,
(((AVPixelFormat)par->format == AV_PIX_FMT_NONE) ? "none" : av_get_pix_fmt_name((AVPixelFormat)par->format))
);
}
#endif

View File

@ -517,19 +517,19 @@ int FfmpegCamera::OpenFfmpeg() {
Debug(1, "Selected hw_pix_fmt %d %s",
hw_pix_fmt, av_get_pix_fmt_name(hw_pix_fmt));
mVideoCodecContext->get_format = get_hw_format;
ret = av_hwdevice_ctx_create(&hw_device_ctx, type,
(hwaccel_device != "" ? hwaccel_device.c_str(): NULL), NULL, 0);
if ( ret < 0 ) {
Error("Failed to create hwaccel device.");
return -1;
Error("Failed to create hwaccel device. %s",av_make_error_string(ret).c_str());
hw_pix_fmt = AV_PIX_FMT_NONE;
} else {
Debug(1, "Created hwdevice for %s", hwaccel_device.c_str());
mVideoCodecContext->get_format = get_hw_format;
mVideoCodecContext->hw_device_ctx = av_buffer_ref(hw_device_ctx);
hwFrame = zm_av_frame_alloc();
}
Debug(1, "Created hwdevice for %s", hwaccel_device.c_str());
mVideoCodecContext->hw_device_ctx = av_buffer_ref(hw_device_ctx);
hwFrame = zm_av_frame_alloc();
} else {
Debug(1, "Failed to setup hwaccel.");
Debug(1, "Failed to find suitable hw_pix_fmt.");
}
#else
Debug(1, "AVCodec not new enough for hwaccel");
@ -537,7 +537,7 @@ int FfmpegCamera::OpenFfmpeg() {
#else
Warning("HWAccel support not compiled in.");
#endif
} // end if hwacel_name
} // end if hwaccel_name
// Open the codec
#if !LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 8, 0)
@ -1087,6 +1087,7 @@ int FfmpegCamera::transfer_to_image(
return -1;
}
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
// From what I've read, we should align the linesizes to 32bit so that ffmpeg can use SIMD instructions too.
int size = av_image_fill_arrays(
output_frame->data, output_frame->linesize,
directbuffer, imagePixFormat, width, height, 32);
@ -1128,8 +1129,8 @@ int FfmpegCamera::transfer_to_image(
mConvertContext, input_frame->data, input_frame->linesize,
0, mVideoCodecContext->height,
output_frame->data, output_frame->linesize);
if ( ret <= 0 ) {
Error("Unable to convert format %u %s linesize %d height %d to format %u %s linesize %d at frame %d codec %u %s : code: %d",
if ( ret < 0 ) {
Error("Unable to convert format %u %s linesize %d height %d to format %u %s linesize %d at frame %d codec %u %s lines %d: code: %d",
input_frame->format, av_get_pix_fmt_name((AVPixelFormat)input_frame->format),
input_frame->linesize, mVideoCodecContext->height,
imagePixFormat,
@ -1137,6 +1138,7 @@ int FfmpegCamera::transfer_to_image(
output_frame->linesize,
frameCount,
mVideoCodecContext->pix_fmt, av_get_pix_fmt_name(mVideoCodecContext->pix_fmt),
mVideoCodecContext->height,
ret
);
return -1;

View File

@ -156,6 +156,7 @@ void Logger::initialise(const std::string &id, const Options &options) {
if ( options.mTerminalLevel != NOOPT )
tempTerminalLevel = options.mTerminalLevel;
// DEBUG1 == 1. So >= DEBUG1, we set to DEBUG9?! Why?
if ( options.mDatabaseLevel != NOOPT )
tempDatabaseLevel = options.mDatabaseLevel;
else
@ -359,7 +360,7 @@ Logger::Level Logger::databaseLevel(Logger::Level databaseLevel) {
if ( databaseLevel > NOOPT ) {
databaseLevel = limit(databaseLevel);
if ( mDatabaseLevel != databaseLevel ) {
if ( databaseLevel > NOLOG && mDatabaseLevel <= NOLOG ) {
if ( (databaseLevel > NOLOG) && (mDatabaseLevel <= NOLOG) ) { // <= NOLOG would be NOOPT
if ( !zmDbConnect() ) {
databaseLevel = NOLOG;
}

View File

@ -1,21 +1,21 @@
//
// ZoneMinder Monitor Class Implementation, $Date$, $Revision$
// Copyright (C) 2001-2008 Philip Coombes
//
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
//
#include "zm.h"
#include "zm_db.h"
@ -73,7 +73,7 @@ bool MonitorStream::checkSwapPath(const char *path, bool create_path) {
return false;
}
return true;
} // end bool MonitorStream::checkSwapPath( const char *path, bool create_path )
} // end bool MonitorStream::checkSwapPath( const char *path, bool create_path )
void MonitorStream::processCommand(const CmdMsg *msg) {
Debug( 2, "Got message, type %d, msg %d", msg->msg_type, msg->msg_data[0] );
@ -265,7 +265,7 @@ void MonitorStream::processCommand(const CmdMsg *msg) {
//status_data.enabled = monitor->shared_data->active;
status_data.enabled = monitor->trigger_data->trigger_state!=Monitor::TRIGGER_OFF;
status_data.forced = monitor->trigger_data->trigger_state==Monitor::TRIGGER_ON;
Debug(2, "Buffer Level:%d, Delayed:%d, Paused:%d, Rate:%d, delay:%.3f, Zoom:%d, Enabled:%d Forced:%d",
Debug(2, "Buffer Level:%d, Delayed:%d, Paused:%d, Rate:%d, delay:%.3f, Zoom:%d, Enabled:%d Forced:%d",
status_data.buffer_level,
status_data.delayed,
status_data.paused,
@ -327,7 +327,7 @@ bool MonitorStream::sendFrame(const char *filepath, struct timeval *timestamp) {
// Calculate how long it takes to actually send the frame
struct timeval frameStartTime;
gettimeofday(&frameStartTime, NULL);
fputs("--ZoneMinderFrame\r\nContent-Type: image/jpeg\r\n", stdout);
fprintf(stdout, "Content-Length: %d\r\n\r\n", img_buffer_size);
if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) {
@ -383,7 +383,7 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
// Calculate how long it takes to actually send the frame
struct timeval frameStartTime;
gettimeofday(&frameStartTime, NULL);
fputs("--ZoneMinderFrame\r\n", stdout);
switch( type ) {
case STREAM_JPEG :
@ -412,7 +412,7 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
}
fprintf(stdout, "Content-Length: %d\r\n\r\n", img_buffer_size);
if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) {
if ( !zm_terminate ) {
if ( !zm_terminate ) {
// If the pipe was closed, we will get signalled SIGPIPE to exit, which will set zm_terminate
Warning("Unable to send stream frame: %s", strerror(errno));
}
@ -430,7 +430,7 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
Warning("Frame send time %d msec too slow, throttling maxfps to %.2f",
frameSendTime, maxfps);
}
}
} // Not mpeg
last_frame_sent = TV_2_FLOAT(now);
return true;
} // end bool MonitorStream::sendFrame( Image *image, struct timeval *timestamp )
@ -455,7 +455,7 @@ void MonitorStream::runStream() {
fputs("Content-Type: multipart/x-mixed-replace;boundary=ZoneMinderFrame\r\n\r\n", stdout);
// point to end which is theoretically not a valid value because all indexes are % image_buffer_count
unsigned int last_read_index = monitor->image_buffer_count;
unsigned int last_read_index = monitor->image_buffer_count;
time_t stream_start_time;
time(&stream_start_time);
@ -474,22 +474,21 @@ void MonitorStream::runStream() {
Image *paused_image = NULL;
struct timeval paused_timestamp;
// 15 is the max length for the swap path suffix, /zmswap-whatever, assuming max 6 digits for monitor id
const int max_swap_len_suffix = 15;
int swap_path_length = staticConfig.PATH_SWAP.length() + 1; // +1 for NULL terminator
int subfolder1_length = snprintf(NULL, 0, "/zmswap-m%d", monitor->Id()) + 1;
int subfolder2_length = snprintf(NULL, 0, "/zmswap-q%06d", connkey) + 1;
int total_swap_path_length = swap_path_length + subfolder1_length + subfolder2_length;
if ( connkey && ( playback_buffer > 0 ) ) {
// 15 is the max length for the swap path suffix, /zmswap-whatever, assuming max 6 digits for monitor id
const int max_swap_len_suffix = 15;
int swap_path_length = staticConfig.PATH_SWAP.length() + 1; // +1 for NULL terminator
int subfolder1_length = snprintf(NULL, 0, "/zmswap-m%d", monitor->Id()) + 1;
int subfolder2_length = snprintf(NULL, 0, "/zmswap-q%06d", connkey) + 1;
int total_swap_path_length = swap_path_length + subfolder1_length + subfolder2_length;
if ( total_swap_path_length + max_swap_len_suffix > PATH_MAX ) {
Error("Swap Path is too long. %d > %d ", total_swap_path_length+max_swap_len_suffix, PATH_MAX);
} else {
swap_path = staticConfig.PATH_SWAP;
Debug( 3, "Checking swap path folder: %s", swap_path.c_str() );
Debug(3, "Checking swap path folder: %s", swap_path.c_str());
if ( checkSwapPath(swap_path.c_str(), true) ) {
swap_path += stringtf("/zmswap-m%d", monitor->Id());
@ -509,8 +508,8 @@ void MonitorStream::runStream() {
} else {
Debug(2, "Assigning temporary buffer");
temp_image_buffer = new SwapImage[temp_image_buffer_count];
memset( temp_image_buffer, 0, sizeof(*temp_image_buffer)*temp_image_buffer_count );
Debug( 2, "Assigned temporary buffer" );
memset(temp_image_buffer, 0, sizeof(*temp_image_buffer)*temp_image_buffer_count);
Debug(2, "Assigned temporary buffer");
}
}
} else {
@ -525,7 +524,7 @@ void MonitorStream::runStream() {
Debug(1, "Using %.3f for fps instead of current fps %.3f", capture_max_fps, capture_fps);
capture_fps = capture_max_fps;
}
if ( capture_fps < 1 ) {
max_secs_since_last_sent_frame = 10/capture_fps;
Debug(1, "Adjusting max_secs_since_last_sent_frame to %.2f from current fps %.2f",
@ -562,7 +561,7 @@ void MonitorStream::runStream() {
touch(sock_path_lock);
last_comm_update = now;
}
} // end if connkey
} // end if connkey
if ( paused ) {
if ( !was_paused ) {
@ -589,7 +588,7 @@ void MonitorStream::runStream() {
} else {
if ( !paused ) {
int temp_index = MOD_ADD(temp_read_index, 0, temp_image_buffer_count);
//Debug( 3, "tri: %d, ti: %d", temp_read_index, temp_index );
// Debug( 3, "tri: %d, ti: %d", temp_read_index, temp_index );
SwapImage *swap_image = &temp_image_buffer[temp_index];
if ( !swap_image->valid ) {
@ -597,51 +596,61 @@ void MonitorStream::runStream() {
delayed = true;
temp_read_index = MOD_ADD(temp_read_index, (replay_rate>=0?-1:1), temp_image_buffer_count);
} else {
//Debug( 3, "siT: %f, lfT: %f", TV_2_FLOAT( swap_image->timestamp ), TV_2_FLOAT( last_frame_timestamp ) );
double expected_delta_time = ((TV_2_FLOAT( swap_image->timestamp ) - TV_2_FLOAT( last_frame_timestamp )) * ZM_RATE_BASE)/replay_rate;
double actual_delta_time = TV_2_FLOAT( now ) - last_frame_sent;
// Debug( 3, "siT: %f, lfT: %f", TV_2_FLOAT( swap_image->timestamp ), TV_2_FLOAT( last_frame_timestamp ) );
double expected_delta_time = ((TV_2_FLOAT(swap_image->timestamp) - TV_2_FLOAT(last_frame_timestamp)) * ZM_RATE_BASE)/replay_rate;
double actual_delta_time = TV_2_FLOAT(now) - last_frame_sent;
//Debug( 3, "eDT: %.3lf, aDT: %.3f, lFS:%.3f, NOW:%.3f", expected_delta_time, actual_delta_time, last_frame_sent, TV_2_FLOAT( now ) );
// Debug( 3, "eDT: %.3lf, aDT: %.3f, lFS:%.3f, NOW:%.3f", expected_delta_time, actual_delta_time, last_frame_sent, TV_2_FLOAT( now ) );
// If the next frame is due
if ( actual_delta_time > expected_delta_time ) {
//Debug( 2, "eDT: %.3lf, aDT: %.3f", expected_delta_time, actual_delta_time );
// Debug( 2, "eDT: %.3lf, aDT: %.3f", expected_delta_time, actual_delta_time );
if ( temp_index%frame_mod == 0 ) {
Debug( 2, "Sending delayed frame %d", temp_index );
Debug(2, "Sending delayed frame %d", temp_index);
// Send the next frame
if ( ! sendFrame(temp_image_buffer[temp_index].file_name, &temp_image_buffer[temp_index].timestamp) )
if ( ! sendFrame(temp_image_buffer[temp_index].file_name, &temp_image_buffer[temp_index].timestamp) ) {
zm_terminate = true;
}
memcpy(&last_frame_timestamp, &(swap_image->timestamp), sizeof(last_frame_timestamp));
//frame_sent = true;
// frame_sent = true;
}
temp_read_index = MOD_ADD(temp_read_index, (replay_rate>0?1:-1), temp_image_buffer_count);
}
}
} else if ( step != 0 ) {
temp_read_index = MOD_ADD( temp_read_index, (step>0?1:-1), temp_image_buffer_count );
temp_read_index = MOD_ADD(temp_read_index, (step>0?1:-1), temp_image_buffer_count);
SwapImage *swap_image = &temp_image_buffer[temp_read_index];
// Send the next frame
if ( !sendFrame( temp_image_buffer[temp_read_index].file_name, &temp_image_buffer[temp_read_index].timestamp ) )
if ( !sendFrame(
temp_image_buffer[temp_read_index].file_name,
&temp_image_buffer[temp_read_index].timestamp
) ) {
zm_terminate = true;
memcpy( &last_frame_timestamp, &(swap_image->timestamp), sizeof(last_frame_timestamp) );
//frame_sent = true;
}
memcpy(
&last_frame_timestamp,
&(swap_image->timestamp),
sizeof(last_frame_timestamp)
);
// frame_sent = true;
step = 0;
} else {
//paused?
int temp_index = MOD_ADD(temp_read_index, 0, temp_image_buffer_count);
double actual_delta_time = TV_2_FLOAT( now ) - last_frame_sent;
if ( got_command || actual_delta_time > 5 ) {
double actual_delta_time = TV_2_FLOAT(now) - last_frame_sent;
if ( got_command || (actual_delta_time > 5) ) {
// Send keepalive
Debug(2, "Sending keepalive frame %d", temp_index);
// Send the next frame
if ( !sendFrame( temp_image_buffer[temp_index].file_name, &temp_image_buffer[temp_index].timestamp ) )
if ( !sendFrame(temp_image_buffer[temp_index].file_name, &temp_image_buffer[temp_index].timestamp) ) {
zm_terminate = true;
//frame_sent = true;
}
// frame_sent = true;
}
} // end if (!paused) or step or paused
} // end if have exceeded buffer or not
} // end if (!paused) or step or paused
} // end if have exceeded buffer or not
if ( temp_read_index == temp_write_index ) {
// Go back to live viewing
@ -652,16 +661,16 @@ void MonitorStream::runStream() {
delayed = false;
replay_rate = ZM_RATE_BASE;
}
} // end if ( buffered_playback && delayed )
} // end if ( buffered_playback && delayed )
if ( last_read_index != monitor->shared_data->last_write_index ) {
// have a new image to send
int index = monitor->shared_data->last_write_index % monitor->image_buffer_count; // % shouldn't be neccessary
int index = monitor->shared_data->last_write_index % monitor->image_buffer_count; // % shouldn't be neccessary
if ( (frame_mod == 1) || ((frame_count%frame_mod) == 0) ) {
if ( !paused && !delayed ) {
last_read_index = monitor->shared_data->last_write_index;
Debug(2, "index: %d: frame_mod: %d frame count: %d paused(%d) delayed(%d)",
index, frame_mod, frame_count, paused, delayed );
index, frame_mod, frame_count, paused, delayed);
// Send the next frame
Monitor::Snapshot *snap = &monitor->image_buffer[index];
@ -670,9 +679,13 @@ void MonitorStream::runStream() {
Debug(2, "sendFrame failed, quiting.");
zm_terminate = true;
}
// Perhaps we should use NOW instead.
memcpy(&last_frame_timestamp, snap->timestamp, sizeof(last_frame_timestamp));
//frame_sent = true;
// Perhaps we should use NOW instead.
memcpy(
&last_frame_timestamp,
snap->timestamp,
sizeof(last_frame_timestamp)
);
// frame_sent = true;
temp_read_index = temp_write_index;
} else {
@ -697,7 +710,7 @@ void MonitorStream::runStream() {
if ( !sendFrame(paused_image, &paused_timestamp) )
zm_terminate = true;
} else {
Debug(2, "Would have sent keepalive frame, but had no paused_image ");
Debug(2, "Would have sent keepalive frame, but had no paused_image");
}
} // end if actual_delta_time > 5
} // end if change in zoom
@ -718,27 +731,27 @@ void MonitorStream::runStream() {
temp_index);
temp_image_buffer[temp_index].valid = true;
}
memcpy( &(temp_image_buffer[temp_index].timestamp), monitor->image_buffer[index].timestamp, sizeof(temp_image_buffer[0].timestamp) );
monitor->image_buffer[index].image->WriteJpeg( temp_image_buffer[temp_index].file_name, config.jpeg_file_quality );
temp_write_index = MOD_ADD( temp_write_index, 1, temp_image_buffer_count );
memcpy(&(temp_image_buffer[temp_index].timestamp), monitor->image_buffer[index].timestamp, sizeof(temp_image_buffer[0].timestamp));
monitor->image_buffer[index].image->WriteJpeg(temp_image_buffer[temp_index].file_name, config.jpeg_file_quality);
temp_write_index = MOD_ADD(temp_write_index, 1, temp_image_buffer_count);
if ( temp_write_index == temp_read_index ) {
// Go back to live viewing
Warning( "Exceeded temporary buffer, resuming live play" );
Warning("Exceeded temporary buffer, resuming live play");
paused = false;
delayed = false;
replay_rate = ZM_RATE_BASE;
}
} else {
Warning( "Unable to store frame as timestamp invalid" );
Warning("Unable to store frame as timestamp invalid");
}
} else {
Warning( "Unable to store frame as shared memory invalid" );
Warning("Unable to store frame as shared memory invalid");
}
} // end if buffered playback
frame_count++;
} else {
Debug(3, "Waiting for capture last_write_index=%u", monitor->shared_data->last_write_index);
} // end if ( (unsigned int)last_read_index != monitor->shared_data->last_write_index )
} // end if ( (unsigned int)last_read_index != monitor->shared_data->last_write_index )
unsigned long sleep_time = (unsigned long)((1000000 * ZM_RATE_BASE)/((base_fps?base_fps:1)*abs(replay_rate*2)));
Debug(3, "Sleeping for (%d)", sleep_time);
@ -755,10 +768,10 @@ void MonitorStream::runStream() {
break;
}
}
if ( ! last_frame_sent ) {
if ( !last_frame_sent ) {
// If we didn't capture above, because frame_mod was bad? Then last_frame_sent will not have a value.
last_frame_sent = now.tv_sec;
Warning("no last_frame_sent. Shouldn't happen. frame_mod was (%d) frame_count (%d) ",
Warning("no last_frame_sent. Shouldn't happen. frame_mod was (%d) frame_count (%d)",
frame_mod, frame_count);
} else if (
(!paused)
@ -799,9 +812,9 @@ void MonitorStream::runStream() {
}
}
}
globfree( &pglob );
globfree(&pglob);
if ( rmdir(swap_path.c_str()) < 0 ) {
Error( "Can't rmdir '%s': %s", swap_path.c_str(), strerror(errno) );
Error("Can't rmdir '%s': %s", swap_path.c_str(), strerror(errno));
}
} // end if checking for swap_path
} // end if buffered_playback
@ -809,7 +822,7 @@ void MonitorStream::runStream() {
closeComms();
} // end MonitorStream::runStream
void MonitorStream::SingleImage( int scale ) {
void MonitorStream::SingleImage(int scale) {
int img_buffer_size = 0;
static JOCTET img_buffer[ZM_MAX_IMAGE_SIZE];
Image scaled_image;
@ -817,42 +830,45 @@ void MonitorStream::SingleImage( int scale ) {
Image *snap_image = snap->image;
if ( scale != ZM_SCALE_BASE ) {
scaled_image.Assign( *snap_image );
scaled_image.Scale( scale );
scaled_image.Assign(*snap_image);
scaled_image.Scale(scale);
snap_image = &scaled_image;
}
if ( !config.timestamp_on_capture ) {
monitor->TimestampImage( snap_image, snap->timestamp );
monitor->TimestampImage(snap_image, snap->timestamp);
}
snap_image->EncodeJpeg( img_buffer, &img_buffer_size );
fprintf( stdout, "Content-Length: %d\r\n", img_buffer_size );
fprintf( stdout, "Content-Type: image/jpeg\r\n\r\n" );
fwrite( img_buffer, img_buffer_size, 1, stdout );
snap_image->EncodeJpeg(img_buffer, &img_buffer_size);
fprintf(stdout,
"Content-Length: %d\r\n"
"Content-Type: image/jpeg\r\n\r\n",
img_buffer_size);
fwrite(img_buffer, img_buffer_size, 1, stdout);
}
void MonitorStream::SingleImageRaw( int scale ) {
void MonitorStream::SingleImageRaw(int scale) {
Image scaled_image;
Monitor::Snapshot *snap = monitor->getSnapshot();
Image *snap_image = snap->image;
if ( scale != ZM_SCALE_BASE ) {
scaled_image.Assign( *snap_image );
scaled_image.Scale( scale );
scaled_image.Assign(*snap_image);
scaled_image.Scale(scale);
snap_image = &scaled_image;
}
if ( !config.timestamp_on_capture ) {
monitor->TimestampImage( snap_image, snap->timestamp );
monitor->TimestampImage(snap_image, snap->timestamp);
}
fprintf( stdout, "Content-Length: %d\r\n", snap_image->Size() );
fprintf( stdout, "Content-Type: image/x-rgb\r\n\r\n" );
fwrite( snap_image->Buffer(), snap_image->Size(), 1, stdout );
fprintf(stdout,
"Content-Length: %d\r\n"
"Content-Type: image/x-rgb\r\n\r\n",
snap_image->Size());
fwrite(snap_image->Buffer(), snap_image->Size(), 1, stdout);
}
#ifdef HAVE_ZLIB_H
void MonitorStream::SingleImageZip( int scale ) {
void MonitorStream::SingleImageZip(int scale) {
unsigned long img_buffer_size = 0;
static Bytef img_buffer[ZM_MAX_IMAGE_SIZE];
Image scaled_image;
@ -861,17 +877,19 @@ void MonitorStream::SingleImageZip( int scale ) {
Image *snap_image = snap->image;
if ( scale != ZM_SCALE_BASE ) {
scaled_image.Assign( *snap_image );
scaled_image.Scale( scale );
scaled_image.Assign(*snap_image);
scaled_image.Scale(scale);
snap_image = &scaled_image;
}
if ( !config.timestamp_on_capture ) {
monitor->TimestampImage( snap_image, snap->timestamp );
monitor->TimestampImage(snap_image, snap->timestamp);
}
snap_image->Zip( img_buffer, &img_buffer_size );
fprintf( stdout, "Content-Length: %ld\r\n", img_buffer_size );
fprintf( stdout, "Content-Type: image/x-rgbz\r\n\r\n" );
fwrite( img_buffer, img_buffer_size, 1, stdout );
snap_image->Zip(img_buffer, &img_buffer_size);
fprintf(stdout,
"Content-Length: %ld\r\n"
"Content-Type: image/x-rgbz\r\n\r\n",
img_buffer_size);
fwrite(img_buffer, img_buffer_size, 1, stdout);
}
#endif // HAVE_ZLIB_H

View File

@ -1060,7 +1060,6 @@ int RemoteCameraHttp::PreCapture() {
if ( sd < 0 ) {
Connect();
if ( sd < 0 ) {
Error("Unable to connect to camera");
return -1;
}
mode = SINGLE_IMAGE;

View File

@ -350,7 +350,7 @@ int main(int argc, char *argv[]) {
}
if ( result < 0 ) {
// Failure, try reconnecting
sleep(1);
sleep(5);
break;
}
} // end while ! zm_terminate

View File

@ -175,7 +175,7 @@ cd ../
VERSION=`cat ${GITHUB_FORK}_zoneminder_release/version`
if [ $VERSION == "" ]; then
if [ -z "$VERSION" ]; then
exit 1;
fi;
if [ "$SNAPSHOT" != "stable" ] && [ "$SNAPSHOT" != "" ]; then

View File

@ -1,5 +1,10 @@
#!/bin/bash
# We don't deploy during eslint checks, so exit immediately
if [ "${DIST}" == "eslint" ]; then
exit 0
fi
# Check to see if this script has access to all the commands it needs
for CMD in sshfs rsync find fusermount mkdir; do
type $CMD 2>&1 > /dev/null
@ -12,53 +17,26 @@ for CMD in sshfs rsync find fusermount mkdir; do
fi
done
# We only want to deploy packages during cron events
# See https://docs.travis-ci.com/user/cron-jobs/
if [ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${OS}" == "debian" ] || [ "${OS}" == "ubuntu" ]; then
if [ "${OS}" == "debian" ] || [ "${OS}" == "ubuntu" ]; then
targetfolder="debian/master/mini-dinstall/incoming"
else
targetfolder="travis"
fi
echo
echo "Target subfolder set to $targetfolder"
echo
if [ "${USE_SFTP}" == "yes" ]; then
echo "Running \$(rsync -v -e 'ssh -vvv' build/* zmrepo@zmrepo.zoneminder.com:${targetfolder}/ 2>&1)"
rsync -v -e 'ssh -vvv' build/* zmrepo@zmrepo.zoneminder.com:${targetfolder}/ 2>&1
if [ $? -eq 0 ]; then
echo
echo "Files copied successfully."
echo
else
echo
echo "ERROR: Attempt to rsync to zmrepo.zoneminder.com failed!"
echo
exit 99
fi
else
mkdir -p ./zmrepo
ssh_mntchk="$(sshfs zmrepo@zmrepo.zoneminder.com:./ ./zmrepo -o workaround=rename,reconnect 2>&1)"
if [ -z "$ssh_mntchk" ]; then
echo
echo "Remote filesystem mounted successfully."
echo "Begin transfering files..."
echo
# Don't keep packages older than 5 days
find ./zmrepo/$targetfolder/ -maxdepth 1 -type f,l -mtime +5 -delete
rsync -vzlh --ignore-errors build/* zmrepo/$targetfolder/
fusermount -zu zmrepo
else
echo
echo "ERROR: Attempt to mount zmrepo.zoneminder.com failed!"
echo "sshfs gave the following error message:"
echo \"$ssh_mntchk\"
echo
exit 99
fi
fi
if [ "${OS}" == "debian" ] || [ "${OS}" == "ubuntu" ] || [ "${OS}" == "raspbian" ]; then
targetfolder="debian/master/mini-dinstall/incoming"
else
targetfolder="travis"
fi
echo
echo "Target subfolder set to $targetfolder"
echo
echo "Running \$(rsync -v -e 'ssh -vvv' build/*.{rpm,deb,dsc,tar.xz,buildinfo,changes} zmrepo@zmrepo.zoneminder.com:${targetfolder}/ 2>&1)"
rsync -v --ignore-missing-args --exclude 'external-repo.noarch.rpm' -e 'ssh -vvv' build/*.{rpm,deb,dsc,tar.xz,buildinfo,changes} zmrepo@zmrepo.zoneminder.com:${targetfolder}/ 2>&1
if [ "$?" -eq 0 ]; then
echo
echo "Files copied successfully."
echo
else
echo
echo "ERROR: Attempt to rsync to zmrepo.zoneminder.com failed!"
echo "See log output for details."
echo
exit 99
fi

View File

@ -9,7 +9,7 @@
# General sanity checks
checksanity () {
# Check to see if this script has access to all the commands it needs
for CMD in set echo curl git ln mkdir rmdir cat patch; do
for CMD in set echo curl git ln mkdir rmdir cat patch sed; do
type $CMD 2>&1 > /dev/null
if [ $? -ne 0 ]; then
@ -30,7 +30,7 @@ checksanity () {
ARCH="x86_64"
fi
if [[ "${ARCH}" != "x86_64" && "${ARCH}" != "i386" && "${ARCH}" != "armhf" ]]; then
if [[ "${ARCH}" != "x86_64" && "${ARCH}" != "i386" && "${ARCH}" != "armhf" && "${ARCH}" != "aarch64" ]]; then
echo
echo "ERROR: Unsupported architecture specified \"${ARCH}\"."
echo
@ -150,7 +150,7 @@ install_deb () {
exit 1
fi
# Install and test the zoneminder package (only) for Ubuntu Trusty
# Install and test the zoneminder package (only) for Ubuntu Xenial
pkgname="build/zoneminder_${VERSION}-${RELEASE}_amd64.deb"
if [ -e $pkgname ]; then
@ -275,6 +275,8 @@ checkdeploytarget () {
echo "*** TRACEROUTE ***"
echo
traceroute -w 2 -m 15 ${DEPLOYTARGET}
exit 97
fi
}
@ -291,43 +293,43 @@ if [ "${TRAVIS}" == "true" ]; then
fi
checksanity
# We don't want to build packages for all supported distros after every commit
# Only build all packages when executed via cron
# See https://docs.travis-ci.com/user/cron-jobs/
# Steps common to Redhat distros
if [ "${OS}" == "el" ] || [ "${OS}" == "fedora" ]; then
if [ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${TRAVIS}" != "true" ]; then
commonprep
echo "Begin Redhat build..."
commonprep
echo "Begin Redhat build..."
setrpmpkgname
# Newer Redhat distros use dnf package manager rather than yum
if [ "${DIST}" -gt "7" ]; then
sed -i 's\yum\dnf\' utils/packpack/redhat_package.mk
fi
ln -sfT distros/redhat rpm
setrpmpkgname
# The rpm specfile requires the Crud submodule folder to be empty
rm -rf web/api/app/Plugin/Crud
mkdir web/api/app/Plugin/Crud
ln -sfT distros/redhat rpm
reporpm="rpmfusion-free-release"
dlurl="https://download1.rpmfusion.org/free/${OS}/${reporpm}-${DIST}.noarch.rpm"
# The rpm specfile requires the Crud submodule folder to be empty
rm -rf web/api/app/Plugin/Crud
mkdir web/api/app/Plugin/Crud
# Give our downloaded repo rpm a common name so redhat_package.mk can find it
if [ -n "$dlurl" ] && [ $? -eq 0 ]; then
echo "Retrieving ${reporpm} repo rpm..."
curl $dlurl > build/external-repo.noarch.rpm
else
echo "ERROR: Failed to retrieve ${reporpm} repo rpm..."
echo "Download url was: $dlurl"
exit 1
fi
reporpm="rpmfusion-free-release"
dlurl="https://download1.rpmfusion.org/free/${OS}/${reporpm}-${DIST}.noarch.rpm"
setrpmchangelog
# Give our downloaded repo rpm a common name so redhat_package.mk can find it
if [ -n "$dlurl" ] && [ $? -eq 0 ]; then
echo "Retrieving ${reporpm} repo rpm..."
curl $dlurl > build/external-repo.noarch.rpm
else
echo "ERROR: Failed to retrieve ${reporpm} repo rpm..."
echo "Download url was: $dlurl"
exit 1
fi
echo "Starting packpack..."
execpackpack
fi;
# Steps common to Debian based distros
setrpmchangelog
echo "Starting packpack..."
execpackpack
# Steps common to Debian based distros
elif [ "${OS}" == "debian" ] || [ "${OS}" == "ubuntu" ] || [ "${OS}" == "raspbian" ]; then
commonprep
echo "Begin ${OS} ${DIST} build..."
@ -348,14 +350,27 @@ elif [ "${OS}" == "debian" ] || [ "${OS}" == "ubuntu" ] || [ "${OS}" == "raspbia
echo "Starting packpack..."
execpackpack
# We were not triggered via cron so just build and test trusty
if [ "${OS}" == "ubuntu" ] && [ "${DIST}" == "xenial" ] && [ "${ARCH}" == "x86_64" ]; then
# If we are running inside Travis then attempt to install the deb we just built
if [ "${TRAVIS}" == "true" ]; then
# Try to install and run the newly built zoneminder package
if [ "${OS}" == "ubuntu" ] && [ "${DIST}" == "xenial" ] && [ "${ARCH}" == "x86_64" ] && [ "${TRAVIS}" == "true" ]; then
echo "Begin Deb package installation..."
install_deb
fi
fi
# Steps common to eslint checks
elif [ "${OS}" == "eslint" ] || [ "${DIST}" == "eslint" ]; then
# Check we've got npm installed
type npm 2>&1 > /dev/null
if [ $? -ne 0 ]; then
echo
echo "ERROR: The script cannot find the required command \"npm\"."
echo
exit 1
fi
npm install -g eslint@5.12.0 eslint-config-google@0.11.0 eslint-plugin-html@5.0.0 eslint-plugin-php-markup@0.2.5
echo "Begin eslint checks..."
eslint --ext .php,.js .
fi
exit 0

View File

@ -1 +1 @@
1.33.15
1.34.0

View File

@ -41,7 +41,7 @@ function buildLogQuery($action) {
}
foreach ( $filter as $field=>$value ) {
if ( ! in_array($field, $filterFields) ) {
if ( !in_array($field, $filterFields) ) {
ZM\Error("'$field' is not in valid filter fields " . print_r($filterField,true));
continue;
}
@ -58,7 +58,7 @@ function buildLogQuery($action) {
$sql .= ' ORDER BY '.$sortField.' '.$sortOrder.' LIMIT '.$limit;
return array('sql'=>$sql, 'values'=>$values);
}
} # function buildLogQuery($action)
switch ( $_REQUEST['task'] ) {
case 'create' :
@ -70,14 +70,16 @@ switch ( $_REQUEST['task'] ) {
$string = $_POST['message'];
$file = !empty($_POST['file']) ? preg_replace( '/\w+:\/\/[\w.:]+\//', '', $_POST['file'] ) : '';
if ( !empty( $_POST['line'] ) )
if ( !empty( $_POST['line'] ) ) {
$line = validInt($_POST['line']);
else
} else {
$line = NULL;
}
$levels = array_flip(ZM\Logger::$codes);
if ( !isset($levels[$_POST['level']]) )
if ( !isset($levels[$_POST['level']]) ) {
ZM\Panic('Unexpected logger level '.$_POST['level']);
}
$level = $levels[$_POST['level']];
ZM\Logger::fetch()->logPrint($level, $string, $file, $line);
}
@ -141,6 +143,10 @@ switch ( $_REQUEST['task'] ) {
$logs[] = $log;
}
foreach ( $options as $field => $values ) {
asort($options[$field]);
}
$available = count($logs);
ajaxResponse( array(
'updated' => preg_match('/%/', DATE_FMT_CONSOLE_LONG)?strftime(DATE_FMT_CONSOLE_LONG):date(DATE_FMT_CONSOLE_LONG),

View File

@ -119,13 +119,11 @@ if ( sem_acquire($semaphore,1) !== false ) {
switch ( $data['type'] ) {
case MSG_DATA_WATCH :
$data = unpack('ltype/imonitor/istate/dfps/ilevel/irate/ddelay/izoom/Cdelayed/Cpaused/Cenabled/Cforced', $msg);
ZM\Logger::Debug('FPS: ' . $data['fps']);
$data['fps'] = round( $data['fps'], 2 );
ZM\Logger::Debug('FPS: ' . $data['fps'] );
$data['rate'] /= RATE_BASE;
$data['delay'] = round( $data['delay'], 2 );
$data['zoom'] = round( $data['zoom']/SCALE_BASE, 1 );
if ( ZM_OPT_USE_AUTH && ZM_AUTH_RELAY == 'hashed' ) {
if ( ZM_OPT_USE_AUTH && (ZM_AUTH_RELAY == 'hashed') ) {
$time = time();
// Regenerate auth hash after half the lifetime of the hash
if ( (!isset($_SESSION['AuthHashGeneratedAt'])) or ( $_SESSION['AuthHashGeneratedAt'] < $time - (ZM_AUTH_HASH_TTL * 1800) ) ) {
@ -144,7 +142,7 @@ if ( sem_acquire($semaphore,1) !== false ) {
}
$data['rate'] /= RATE_BASE;
$data['zoom'] = round( $data['zoom']/SCALE_BASE, 1 );
if ( ZM_OPT_USE_AUTH && ZM_AUTH_RELAY == 'hashed' ) {
if ( ZM_OPT_USE_AUTH && (ZM_AUTH_RELAY == 'hashed') ) {
$time = time();
// Regenerate auth hash after half the lifetime of the hash
if ( (!isset($_SESSION['AuthHashGeneratedAt'])) or ( $_SESSION['AuthHashGeneratedAt'] < $time - (ZM_AUTH_HASH_TTL * 1800) ) ) {

View File

@ -77,16 +77,24 @@ class GroupsController extends AppController {
}
$this->Group->create();
if ( $this->Group->save($this->request->data) ) {
if ( $this->request->data['Group']['MonitorIds'] and ! isset($this->request->data['Monitor']) ) {
$this->request->data['Monitor'] = explode(',', $this->request->data['Group']['MonitorIds']);
unset($this->request->data['Group']['MonitorIds']);
}
if ( $this->Group->saveAssociated($this->request->data, array('atomic'=>true)) ) {
return $this->flash(
__('The group has been saved.'),
array('action' => 'index')
);
}
}
$monitors = $this->Group->Monitor->find('list');
} else {
ZM\Error("Failed to save Group");
debug($this->Group->invalidFields());
}
} # end if post
$monitors = $this->Group->Monitor->find('list');
$this->set(compact('monitors'));
}
} # end add
/**
* edit method

View File

@ -136,7 +136,7 @@ class HostController extends AppController {
}*/
$access_issued_at = time();
$access_ttl = (ZM_AUTH_HASH_TTL || 2) * 3600;
$access_ttl = max(ZM_AUTH_HASH_TTL,1) * 3600;
// by default access token will expire in 2 hrs
// you can change it by changing the value of ZM_AUTH_HASH_TLL

View File

@ -44,33 +44,26 @@ class MonitorsController extends AppController {
} else {
$conditions = array();
}
global $user;
$allowedMonitors = $user ? preg_split('@,@', $user['MonitorIds'], NULL, PREG_SPLIT_NO_EMPTY) : null;
if ( $allowedMonitors ) {
$conditions['Monitor.Id' ] = $allowedMonitors;
}
$find_array = array('conditions'=>$conditions,'contain'=>array('Group'));
if ( isset($conditions['GroupId']) ) {
$find_array['joins'] = array(
$find_array = array(
'conditions' => &$conditions,
'contain' => array('Group'),
'joins' => array(
array(
'table' => 'Groups_Monitors',
'type' => 'inner',
'type' => 'left',
'conditions' => array(
'Groups_Monitors.MonitorId = Monitor.Id'
'Groups_Monitors.MonitorId = Monitor.Id',
),
),
//array(
//'table' => 'Groups',
//'type' => 'inner',
//'conditions' => array(
//'Groups.Id = Groups_Monitors.GroupId',
//'Groups.Id' => $this->request->params['GroupId'],
//),
//)
);
}
),
'group' => '`Monitor`.`Id`',
);
$monitors = $this->Monitor->find('all',$find_array);
$this->set(array(
'monitors' => $monitors,

View File

@ -59,7 +59,7 @@ class Group extends AppModel {
*
* @var array
*/
public $hasMany = array(
public $hasAndBelongsToMany = array(
'Monitor' => array(
'className' => 'Monitor',
'joinTable' => 'Groups_Monitors',
@ -77,4 +77,5 @@ class Group extends AppModel {
'counterQuery' => ''
),
);
var $actsAs = array( 'Containable' );
}

View File

@ -128,12 +128,16 @@ class Control extends ZM_Object {
$cmds['PresetHome'] = 'presetHome';
if ( $this->CanZoom() ) {
if ( $this->CanZoomCon() )
if ( $this->CanZoomCon() ) {
$cmds['ZoomRoot'] = 'zoomCon';
elseif ( $this->CanZoomRel() )
} else if ( $this->CanZoomRel() ) {
$cmds['ZoomRoot'] = 'zoomRel';
elseif ( $this->CanZoomAbs() )
} else if ( $this->CanZoomAbs() ) {
$cmds['ZoomRoot'] = 'zoomAbs';
} else {
$cmds['ZoomRoot'] = '';
Error('No zoom type selected. Please select Continuous, Relative, Absolute');
}
$cmds['ZoomTele'] = $cmds['ZoomRoot'].'Tele';
$cmds['ZoomWide'] = $cmds['ZoomRoot'].'Wide';
$cmds['ZoomStop'] = 'zoomStop';
@ -142,12 +146,16 @@ class Control extends ZM_Object {
}
if ( $this->CanFocus() ) {
if ( $this->CanFocusCon() )
if ( $this->CanFocusCon() ) {
$cmds['FocusRoot'] = 'focusCon';
elseif ( $this->CanFocusRel() )
} else if ( $this->CanFocusRel() ) {
$cmds['FocusRoot'] = 'focusRel';
elseif ( $this->CanFocusAbs() )
} else if ( $this->CanFocusAbs() ) {
$cmds['FocusRoot'] = 'focusAbs';
} else {
$cmds['FocusRoot'] = '';
Error('No focus type selected. Please select Continuous, Relative, Absolute');
}
$cmds['FocusFar'] = $cmds['FocusRoot'].'Far';
$cmds['FocusNear'] = $cmds['FocusRoot'].'Near';
$cmds['FocusStop'] = 'focusStop';
@ -156,12 +164,16 @@ class Control extends ZM_Object {
}
if ( $this->CanIris() ) {
if ( $this->CanIrisCon() )
if ( $this->CanIrisCon() ) {
$cmds['IrisRoot'] = 'irisCon';
elseif ( $this->CanIrisRel() )
} else if ( $this->CanIrisRel() ) {
$cmds['IrisRoot'] = 'irisRel';
elseif ( $this->CanIrisAbs() )
} else if ( $this->CanIrisAbs() ) {
$cmds['IrisRoot'] = 'irisAbs';
} else {
$cmds['IrisRoot'] = '';
Error('No iris type selected. Please select Continuous, Relative, Absolute');
}
$cmds['IrisOpen'] = $cmds['IrisRoot'].'Open';
$cmds['IrisClose'] = $cmds['IrisRoot'].'Close';
$cmds['IrisStop'] = 'irisStop';
@ -170,12 +182,16 @@ class Control extends ZM_Object {
}
if ( $this->CanWhite() ) {
if ( $this->CanWhiteCon() )
if ( $this->CanWhiteCon() ) {
$cmds['WhiteRoot'] = 'whiteCon';
elseif ( $this->CanWhiteRel() )
} else if ( $this->CanWhiteRel() ) {
$cmds['WhiteRoot'] = 'whiteRel';
elseif ( $this->CanWhiteAbs() )
} else if ( $this->CanWhiteAbs() ) {
$cmds['WhiteRoot'] = 'whiteAbs';
} else {
Error('No White type selected. Please select Continuous, Relative, Absolute');
$cmds['WhiteRoot'] = '';
}
$cmds['WhiteIn'] = $cmds['WhiteRoot'].'In';
$cmds['WhiteOut'] = $cmds['WhiteRoot'].'Out';
$cmds['WhiteAuto'] = 'whiteAuto';
@ -183,12 +199,16 @@ class Control extends ZM_Object {
}
if ( $this->CanGain() ) {
if ( $this->CanGainCon() )
if ( $this->CanGainCon() ) {
$cmds['GainRoot'] = 'gainCon';
elseif ( $this->CanGainRel() )
} else if ( $this->CanGainRel() ) {
$cmds['GainRoot'] = 'gainRel';
elseif ( $this->CanGainAbs() )
} else if ( $this->CanGainAbs() ) {
$cmds['GainRoot'] = 'gainAbs';
} else {
Error('No Gain type selected');
$cmds['GainRoot'] = '';
}
$cmds['GainUp'] = $cmds['GainRoot'].'Up';
$cmds['GainDown'] = $cmds['GainRoot'].'Down';
$cmds['GainAuto'] = 'gainAuto';
@ -207,6 +227,7 @@ class Control extends ZM_Object {
$cmds['Center'] = $cmds['PresetHome'];
} else {
$cmds['MoveRoot'] = '';
Error('No move type selected. Please select Continuous, Relative, Absolute');
}
$cmds['MoveUp'] = $cmds['MoveRoot'].'Up';

View File

@ -47,6 +47,10 @@ class Event extends ZM_Object {
return ZM_Object::_find_one(get_class(), $parameters, $options);
}
public static function clear_cache() {
return ZM_Object::_clear_cache(get_class());
}
public function Storage( $new = null ) {
if ( $new ) {
$this->{'Storage'} = $new;

View File

@ -115,13 +115,17 @@ class Filter extends ZM_Object {
public function control($command, $server_id=null) {
$Servers = $server_id ? Server::find(array('Id'=>$server_id)) : Server::find(array('Status'=>'Running'));
if ( !count($Servers) and !$server_id ) {
# This will be the non-multi-server case
$Servers = array(new Server());
if ( !count($Servers) ) {
if ( !$server_id ) {
# This will be the non-multi-server case
$Servers = array(new Server());
} else {
Warning("Server not found for id $server_id");
}
}
foreach ( $Servers as $Server ) {
if ( !defined('ZM_SERVER_ID') or !$Server->Id() or ZM_SERVER_ID==$Server->Id() ) {
if ( (!defined('ZM_SERVER_ID')) or (!$Server->Id()) or (ZM_SERVER_ID==$Server->Id()) ) {
# Local
Logger::Debug("Controlling filter locally $command for server ".$Server->Id());
daemonControl($command, 'zmfilter.pl', '--filter_id='.$this->{'Id'}.' --daemon');
@ -139,7 +143,7 @@ class Filter extends ZM_Object {
$url = '?user='.$_SESSION['username'];
}
}
$url .= '&view=filter&action=control&command='.$command.'&Id='.$this->Id().'&ServerId='.$Server->Id();
$url .= '&view=filter&object=filter&action=control&command='.$command.'&Id='.$this->Id().'&ServerId='.$Server->Id();
Logger::Debug("sending command to $url");
$data = array();
if ( defined('ZM_ENABLE_CSRF_MAGIC') ) {

View File

@ -9,111 +9,112 @@ require_once('Storage.php');
class Monitor extends ZM_Object {
protected static $table = 'Monitors';
protected $defaults = array(
'Id' => null,
'Name' => '',
'ServerId' => 0,
'StorageId' => 0,
'Type' => 'Ffmpeg',
'Function' => 'Mocord',
'Enabled' => array('type'=>'boolean','default'=>1),
'LinkedMonitors' => array('type'=>'set', 'default'=>null),
'Triggers' => array('type'=>'set','default'=>''),
'Device' => '',
'Channel' => 0,
'Format' => '0',
'V4LMultiBuffer' => null,
'V4LCapturesPerFrame' => 1,
'Protocol' => null,
'Method' => '',
'Host' => null,
'Port' => '',
'SubPath' => '',
'Path' => null,
'Options' => null,
'User' => null,
'Pass' => null,
// These are NOT NULL default 0 in the db, but 0 is not a valid value. FIXME
'Width' => null,
'Height' => null,
'Colours' => 4,
'Palette' => '0',
'Orientation' => null,
'Deinterlacing' => 0,
'DecoderHWAccelName' => null,
'DecoderHWAccelDevice' => null,
'SaveJPEGs' => 3,
'VideoWriter' => '0',
'OutputCodec' => null,
'OutputContainer' => null,
'EncoderParameters' => "# Lines beginning with # are a comment \n# For changing quality, use the crf option\n# 1 is best, 51 is worst quality\n#crf=23\n",
'RecordAudio' => array('type'=>'boolean', 'default'=>0),
'RTSPDescribe' => array('type'=>'boolean','default'=>0),
'Brightness' => -1,
'Contrast' => -1,
'Hue' => -1,
'Colour' => -1,
'EventPrefix' => 'Event-',
'LabelFormat' => '%N - %d/%m/%y %H:%M:%S',
'LabelX' => 0,
'LabelY' => 0,
'LabelSize' => 1,
'ImageBufferCount' => 100,
'WarmupCount' => 0,
'PreEventCount' => 0,
'PostEventCount' => 0,
'StreamReplayBuffer' => 0,
'AlarmFrameCount' => 1,
'SectionLength' => 600,
'MinSectionLength' => 10,
'FrameSkip' => 0,
'MotionFrameSkip' => 0,
'AnalysisFPSLimit' => null,
'AnalysisUpdateDelay' => 0,
'MaxFPS' => null,
'AlarmMaxFPS' => null,
'FPSReportInterval' => 100,
'RefBlendPerc' => 6,
'AlarmRefBlendPerc' => 6,
'Controllable' => array('type'=>'boolean','default'=>0),
'ControlId' => null,
'ControlDevice' => null,
'ControlAddress' => null,
'AutoStopTimeout' => null,
'TrackMotion' => array('type'=>'boolean','default'=>0),
'TrackDelay' => null,
'ReturnLocation' => -1,
'ReturnDelay' => null,
'DefaultRate' => 100,
'DefaultScale' => 100,
'SignalCheckPoints' => 0,
'SignalCheckColour' => '#0000BE',
'WebColour' => 'red',
'Exif' => array('type'=>'boolean','default'=>0),
'Sequence' => null,
'TotalEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'TotalEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'HourEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'HourEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'DayEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'DayEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'WeekEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'WeekEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'MonthEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'MonthEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'ArchivedEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'ArchivedEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'ZoneCount' => 0,
'Refresh' => null,
'DefaultCodec' => 'auto',
'GroupIds' => array('default'=>array(), 'do_not_update'=>1),
);
private $status_fields = array(
'Status' => null,
'AnalysisFPS' => null,
'CaptureFPS' => null,
'CaptureBandwidth' => null,
);
protected $defaults = array(
'Id' => null,
'Name' => '',
'Notes' => '',
'ServerId' => 0,
'StorageId' => 0,
'Type' => 'Ffmpeg',
'Function' => 'Mocord',
'Enabled' => array('type'=>'boolean','default'=>1),
'LinkedMonitors' => array('type'=>'set', 'default'=>null),
'Triggers' => array('type'=>'set','default'=>''),
'Device' => '',
'Channel' => 0,
'Format' => '0',
'V4LMultiBuffer' => null,
'V4LCapturesPerFrame' => 1,
'Protocol' => null,
'Method' => '',
'Host' => null,
'Port' => '',
'SubPath' => '',
'Path' => null,
'Options' => null,
'User' => null,
'Pass' => null,
// These are NOT NULL default 0 in the db, but 0 is not a valid value. FIXME
'Width' => null,
'Height' => null,
'Colours' => 4,
'Palette' => '0',
'Orientation' => null,
'Deinterlacing' => 0,
'DecoderHWAccelName' => null,
'DecoderHWAccelDevice' => null,
'SaveJPEGs' => 3,
'VideoWriter' => '0',
'OutputCodec' => null,
'OutputContainer' => null,
'EncoderParameters' => "# Lines beginning with # are a comment \n# For changing quality, use the crf option\n# 1 is best, 51 is worst quality\n#crf=23\n",
'RecordAudio' => array('type'=>'boolean', 'default'=>0),
'RTSPDescribe' => array('type'=>'boolean','default'=>0),
'Brightness' => -1,
'Contrast' => -1,
'Hue' => -1,
'Colour' => -1,
'EventPrefix' => 'Event-',
'LabelFormat' => '%N - %d/%m/%y %H:%M:%S',
'LabelX' => 0,
'LabelY' => 0,
'LabelSize' => 1,
'ImageBufferCount' => 20,
'WarmupCount' => 0,
'PreEventCount' => 5,
'PostEventCount' => 5,
'StreamReplayBuffer' => 0,
'AlarmFrameCount' => 1,
'SectionLength' => 600,
'MinSectionLength' => 10,
'FrameSkip' => 0,
'MotionFrameSkip' => 0,
'AnalysisFPSLimit' => null,
'AnalysisUpdateDelay' => 0,
'MaxFPS' => null,
'AlarmMaxFPS' => null,
'FPSReportInterval' => 100,
'RefBlendPerc' => 6,
'AlarmRefBlendPerc' => 6,
'Controllable' => array('type'=>'boolean','default'=>0),
'ControlId' => null,
'ControlDevice' => null,
'ControlAddress' => null,
'AutoStopTimeout' => null,
'TrackMotion' => array('type'=>'boolean','default'=>0),
'TrackDelay' => null,
'ReturnLocation' => -1,
'ReturnDelay' => null,
'DefaultRate' => 100,
'DefaultScale' => 100,
'SignalCheckPoints' => 0,
'SignalCheckColour' => '#0000BE',
'WebColour' => '#ff0000',
'Exif' => array('type'=>'boolean','default'=>0),
'Sequence' => null,
'TotalEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'TotalEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'HourEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'HourEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'DayEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'DayEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'WeekEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'WeekEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'MonthEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'MonthEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'ArchivedEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'ArchivedEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'ZoneCount' => 0,
'Refresh' => null,
'DefaultCodec' => 'auto',
'GroupIds' => array('default'=>array(), 'do_not_update'=>1),
);
private $status_fields = array(
'Status' => null,
'AnalysisFPS' => null,
'CaptureFPS' => null,
'CaptureBandwidth' => null,
);
public function Control() {
if ( !property_exists($this, 'Control') ) {
@ -127,7 +128,14 @@ private $status_fields = array(
}
public function Server() {
return new Server($this->{'ServerId'});
if ( !property_exists($this, 'Server') ) {
if ( $this->ServerId() )
$this->{'Server'} = Server::find_one(array('Id'=>$this->{'ServerId'}));
if ( !property_exists($this, 'Server') ) {
$this->{'Server'} = new Server();
}
}
return $this->{'Server'};
}
public function __call($fn, array $args){
@ -472,53 +480,53 @@ private $status_fields = array(
//ZM_MIN_STREAMING_PORT ? (ZM_MIN_STREAMING_PORT+$this->Id()) : null);
}
public function sendControlCommand($command) {
// command is generally a command option list like --command=blah but might be just the word quit
public function sendControlCommand($command) {
// command is generally a command option list like --command=blah but might be just the word quit
$options = array();
# Convert from a command line params to an option array
foreach ( explode(' ', $command) as $option ) {
if ( preg_match('/--([^=]+)(?:=(.+))?/', $option, $matches) ) {
$options[$matches[1]] = $matches[2]?$matches[2]:1;
} else if ( $option != '' and $option != 'quit' ) {
Warning("Ignored command for zmcontrol $option in $command");
}
}
if ( !count($options) ) {
if ( $command == 'quit' ) {
$options['command'] = 'quit';
} else {
Warning("No commands to send to zmcontrol from $command");
return false;
}
}
if ( (!defined('ZM_SERVER_ID')) or ( property_exists($this, 'ServerId') and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) {
# Local
Logger::Debug('Trying to send options ' . print_r($options, true));
$optionString = jsonEncode($options);
Logger::Debug("Trying to send options $optionString");
// Either connects to running zmcontrol.pl or runs zmcontrol.pl to send the command.
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
if ( $socket < 0 ) {
Error('socket_create() failed: '.socket_strerror($socket));
return false;
}
$sockFile = ZM_PATH_SOCKS.'/zmcontrol-'.$this->{'Id'}.'.sock';
if ( @socket_connect($socket, $sockFile) ) {
if ( !socket_write($socket, $optionString) ) {
Error('Can\'t write to control socket: '.socket_strerror(socket_last_error($socket)));
return false;
$options = array();
# Convert from a command line params to an option array
foreach ( explode(' ', $command) as $option ) {
if ( preg_match('/--([^=]+)(?:=(.+))?/', $option, $matches) ) {
$options[$matches[1]] = $matches[2]?$matches[2]:1;
} else if ( $option != '' and $option != 'quit' ) {
Warning("Ignored command for zmcontrol $option in $command");
}
} else if ( $command != 'quit' ) {
$command = ZM_PATH_BIN.'/zmcontrol.pl '.$command.' --id='.$this->{'Id'};
// Can't connect so use script
$ctrlOutput = exec(escapeshellcmd($command));
}
socket_close($socket);
} else if ( $this->ServerId() ) {
if ( !count($options) ) {
if ( $command == 'quit' ) {
$options['command'] = 'quit';
} else {
Warning("No commands to send to zmcontrol from $command");
return false;
}
}
if ( (!defined('ZM_SERVER_ID')) or ( property_exists($this, 'ServerId') and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) {
# Local
Logger::Debug('Trying to send options ' . print_r($options, true));
$optionString = jsonEncode($options);
Logger::Debug("Trying to send options $optionString");
// Either connects to running zmcontrol.pl or runs zmcontrol.pl to send the command.
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
if ( $socket < 0 ) {
Error('socket_create() failed: '.socket_strerror($socket));
return false;
}
$sockFile = ZM_PATH_SOCKS.'/zmcontrol-'.$this->{'Id'}.'.sock';
if ( @socket_connect($socket, $sockFile) ) {
if ( !socket_write($socket, $optionString) ) {
Error('Can\'t write to control socket: '.socket_strerror(socket_last_error($socket)));
return false;
}
} else if ( $command != 'quit' ) {
$command = ZM_PATH_BIN.'/zmcontrol.pl '.$command.' --id='.$this->{'Id'};
// Can't connect so use script
$ctrlOutput = exec(escapeshellcmd($command));
}
socket_close($socket);
} else if ( $this->ServerId() ) {
$Server = $this->Server();
$url = ZM_BASE_PROTOCOL . '://'.$Server->Hostname().'/zm/api/monitors/daemonControl/'.$this->{'Id'}.'/'.$mode.'/zmcontrol.json';
@ -543,7 +551,7 @@ public function sendControlCommand($command) {
}
} catch ( Exception $e ) {
Error("Except $e thrown trying to restart zma");
return false;
return false;
}
} else {
Error('Server not assigned to Monitor in a multi-server setup. Please assign a server to the Monitor.');

View File

@ -110,8 +110,9 @@ class ZM_Object {
public static function _find_one($class, $parameters = array(), $options = array() ) {
global $object_cache;
if ( ! isset($object_cache[$class]) )
if ( ! isset($object_cache[$class]) ) {
$object_cache[$class] = array();
}
$cache = &$object_cache[$class];
if (
( count($parameters) == 1 ) and
@ -127,6 +128,11 @@ class ZM_Object {
return $results[0];
}
public static function _clear_cache($class) {
global $object_cache;
$object_cache[$class] = array();
}
public static function Objects_Indexed_By_Id($class) {
$results = array();
foreach ( ZM_Object::_find($class, null, array('order'=>'lower(Name)')) as $Object ) {
@ -290,6 +296,18 @@ Logger::Debug("$k => Have default for $v: ");
$this->set($new_values);
}
# Set defaults. Note that we only replace "" with null, not other values
# because for example if we want to clear TimestampFormat, we clear it, but the default is a string value
foreach ( $this->defaults as $field => $default ) {
if ( (!array_key_exists($field, $this)) or ($this->{$field} == '') ) {
if ( is_array($default) ) {
$this->{$field} = $default['default'];
} else if ( $default == null ) {
$this->{$field} = $default;
}
}
}
$fields = array_filter(
$this->defaults,
function($v) {

View File

@ -58,6 +58,13 @@ class Storage extends ZM_Object {
return $this->{'Events'};
}
public function EventCount() {
if ( (! property_exists($this, 'EventCount')) or (!$this->{'EventCount'}) ) {
$this->{'EventCount'} = dbFetchOne('SELECT COUNT(*) AS EventCount FROM Events WHERE StorageId=?', 'EventCount', array($this->Id()));
}
return $this->{'EventCount'};
}
public function disk_usage_percent() {
$path = $this->Path();
if ( ! $path ) {
@ -116,13 +123,14 @@ class Storage extends ZM_Object {
$used = dbFetchOne('SELECT SUM(DiskSpace) AS DiskSpace FROM Events WHERE StorageId=? AND DiskSpace IS NOT NULL', 'DiskSpace', array($this->Id()));
do {
# Do in batches of 1000 so as to not useup all ram
# Do in batches of 1000 so as to not useup all ram, Event will do caching though...
$events = Event::find(array('StorageId'=>$this->Id(), 'DiskSpace'=>null), array('limit'=>1000));
foreach ( $events as $Event ) {
$Event->Storage($this); // Prevent further db hit
# DiskSpace will update the event
$used += $Event->DiskSpace();
} #end foreach
Event::clear_cache();
} while ( count($events) == 1000 );
$this->{'DiskSpace'} = $used;
}

View File

@ -28,6 +28,65 @@ if ( $action == 'controlcap' ) {
require_once('includes/Control.php');
$Control = new ZM\Control( !empty($_REQUEST['cid']) ? $_REQUEST['cid'] : null );
$field_defaults = array(
'CanWake' => 0,
'CanSleep' => 0,
'CanReset' => 0,
'CanReboot' => 0,
'CanMove' => 0,
'CanMoveDiag' => 0,
'CanMoveMap' => 0,
'CanMoveRel' => 0,
'CanMoveAbs' => 0,
'CanMoveCon' => 0,
'CanPan' => 0,
'HasPanSpeed' => 0,
'HasTurboPan' => 0,
'CanTilt' => 0,
'HasTiltSpeed' => 0,
'HasTurboTilt' => 0,
'CanZoom' => 0,
'CanZoomRel' => 0,
'CanZoomAbs' => 0,
'CanZoomCon' => 0,
'HasZoomSpeed' => 0,
'CanFocus' => 0,
'CanAutoFocus' => 0,
'CanFocusRel' => 0,
'CanFocusAbs' => 0,
'CanFocusCon' => 0,
'HasFocusSpeed' => 0,
'CanGain' => 0,
'CanAutoGain' => 0,
'CanGainRel' => 0,
'CanGainAbs' => 0,
'CanGainCon' => 0,
'HasGainSpeed' => 0,
'CanWhite' => 0,
'CanAutoWhite' => 0,
'CanWhiteRel' => 0,
'CanWhiteAbs' => 0,
'CanWhiteCon' => 0,
'HasWhiteSpeed' => 0,
'CanIris' => 0,
'CanAutoIris' => 0,
'CanIrisRel' => 0,
'CanIrisAbs' => 0,
'CanIrisCon' => 0,
'HasIrisSpeed' => 0,
'HasPresets' => 0,
'HasHomePreset' => 0,
'CanSetPresets' => 0,
);
# Checkboxes don't return an element in the POST data, so won't be present in newControl.
# So force a value for these fields
foreach ( $field_defaults as $field => $value ) {
if ( ! (isset($_REQUEST['newControl'][$field]) and $_REQUEST['newControl'][$field]) ) {
$_REQUEST['newControl'][$field] = $value;
}
} # end foreach type
//$changes = getFormChanges( $control, $_REQUEST['newControl'], $types, $columns );
$Control->save($_REQUEST['newControl']);
$refreshParent = true;

View File

@ -64,35 +64,12 @@ if ( isset($_REQUEST['object']) and ( $_REQUEST['object'] == 'filter' ) ) {
$_REQUEST['filter']['Background'] = empty($_REQUEST['filter']['Background']) ? 0 : 1;
$_REQUEST['filter']['Concurrent'] = empty($_REQUEST['filter']['Concurrent']) ? 0 : 1;
$changes = $filter->changes($_REQUEST['filter']);
ZM\Logger::Debug("Changes: " . print_r($changes,true));
if ( 0 ) {
$sql .= ', Query = '.dbEscape(jsonEncode($_REQUEST['filter']['Query']));
$sql .= ', AutoArchive = '.(!empty($_REQUEST['filter']['AutoArchive']) ? 1 : 0);
$sql .= ', AutoVideo = '. ( !empty($_REQUEST['filter']['AutoVideo']) ? 1 : 0);
$sql .= ', AutoUpload = '. ( !empty($_REQUEST['filter']['AutoUpload']) ? 1 : 0);
$sql .= ', AutoEmail = '. ( !empty($_REQUEST['filter']['AutoEmail']) ? 1 : 0);
$sql .= ', AutoMessage = '. ( !empty($_REQUEST['filter']['AutoMessage']) ? 1 : 0);
$sql .= ', AutoExecute = '. ( !empty($_REQUEST['filter']['AutoExecute']) ? 1 : 0);
$sql .= ', AutoExecuteCmd = '.dbEscape($_REQUEST['filter']['AutoExecuteCmd']);
$sql .= ', AutoDelete = '. ( !empty($_REQUEST['filter']['AutoDelete']) ? 1 : 0);
if ( !empty($_REQUEST['filter']['AutoMove']) ? 1 : 0) {
$sql .= ', AutoMove = 1, AutoMoveTo='. validInt($_REQUEST['filter']['AutoMoveTo']);
} else {
$sql .= ', AutoMove = 0';
}
$sql .= ', UpdateDiskSpace = '. ( !empty($_REQUEST['filter']['UpdateDiskSpace']) ? 1 : 0);
$sql .= ', Background = '. ( !empty($_REQUEST['filter']['Background']) ? 1 : 0);
$sql .= ', Concurrent = '. ( !empty($_REQUEST['filter']['Concurrent']) ? 1 : 0);
}
ZM\Logger::Debug('Changes: ' . print_r($changes,true));
if ( $_REQUEST['Id'] and ( $action == 'Save' ) ) {
if ( 0 ) {
dbQuery('UPDATE Filters SET '.$sql.' WHERE Id=?', array($_REQUEST['Id']));
}
$filter->save($changes);
if ( $filter->Background() )
$filter->control('stop');
$filter->save($changes);
} else {
if ( $action == 'execute' ) {

View File

@ -219,7 +219,6 @@ if ( $action == 'monitor' ) {
} else {
ZM\Error('Error saving new Monitor.');
$error_message = dbError($sql);
return;
}
}

View File

@ -179,14 +179,14 @@ if ( ! defined('ZM_SERVER_ID') ) {
# Use Server lookup so that it caches
$Server = ZM\Server::find_one(array('Name'=>ZM_SERVER_NAME));
if ( !$Server ) {
Error('Invalid Multi-Server configration detected. ZM_SERVER_NAME set to ' . ZM_SERVER_NAME . ' in zm.conf, but no corresponding entry found in Servers table.');
ZM\Error('Invalid Multi-Server configration detected. ZM_SERVER_NAME set to ' . ZM_SERVER_NAME . ' in zm.conf, but no corresponding entry found in Servers table.');
} else {
define('ZM_SERVER_ID', $Server->Id());
}
} else if ( defined('ZM_SERVER_HOST') and ZM_SERVER_HOST ) {
$Server = ZM\Server::find_one(array('Name'=>ZM_SERVER_HOST));
if ( ! $Server ) {
Error('Invalid Multi-Server configration detected. ZM_SERVER_HOST set to ' . ZM_SERVER_HOST . ' in zm.conf, but no corresponding entry found in Servers table.');
ZM\Error('Invalid Multi-Server configration detected. ZM_SERVER_HOST set to ' . ZM_SERVER_HOST . ' in zm.conf, but no corresponding entry found in Servers table.');
} else {
define('ZM_SERVER_ID', $Server->Id());
}
@ -199,7 +199,7 @@ function process_configfile($configFile) {
if ( is_readable( $configFile ) ) {
$configvals = array();
$cfg = fopen($configFile, 'r') or Error("Could not open config file: $configFile.");
$cfg = fopen($configFile, 'r') or ZM\Error("Could not open config file: $configFile.");
while ( !feof($cfg) ) {
$str = fgets($cfg, 256);
if ( preg_match('/^\s*(#.*)?$/', $str) ) {
@ -207,7 +207,7 @@ function process_configfile($configFile) {
} else if ( preg_match( '/^\s*([^=\s]+)\s*=\s*[\'"]*(.*?)[\'"]*\s*$/', $str, $matches )) {
$configvals[$matches[1]] = $matches[2];
} else {
Error("Malformed line in config $configFile\n$str");
ZM\Error("Malformed line in config $configFile\n$str");
}
}
fclose($cfg);

View File

@ -409,6 +409,11 @@ ZM\Logger::Debug("Event type: " . gettype($event));
global $user;
if ( $event->Archived() ) {
ZM\Info('Cannot delete Archived event.');
return;
} # end if Archived
if ( $user['Events'] == 'Edit' ) {
$event->delete();
} # CAN EDIT
@ -1082,15 +1087,10 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&amp;') {
$validQueryConjunctionTypes = getFilterQueryConjunctionTypes();
$StorageArea = NULL;
$terms = isset($filter['Query']) ? $filter['Query']['terms'] : NULL;
if ( !isset($terms) ) {
$backTrace = debug_backtrace();
$file = $backTrace[1]['file'];
$line = $backTrace[1]['line'];
ZM\Warning("No terms in filter from $file:$line");
ZM\Warning(print_r($filter, true));
}
if ( isset($terms) && count($terms) ) {
# It is not possible to pass an empty array in the url, so we have to deal with there not being a terms field.
$terms = (isset($filter['Query']) and isset($filter['Query']['terms']) and is_array($filter['Query']['terms'])) ? $filter['Query']['terms'] : array();
if ( count($terms) ) {
for ( $i = 0; $i < count($terms); $i++ ) {
$term = $terms[$i];
@ -1267,7 +1267,7 @@ ZM\Logger::Debug("Term: " . print_r($term,true));
case 'StartDateTime':
case 'EndDateTime':
if ( $value != 'NULL' )
$value = '\''.strftime( STRF_FMT_DATETIME_DB, strtotime( $value ) ).'\'';
$value = '\''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\'';
break;
case 'Date':
case 'StartDate':
@ -1335,10 +1335,10 @@ ZM\Logger::Debug("Term: " . print_r($term,true));
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][val]").'='.urlencode($term['val']);
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[Query][terms][$i][val]\" value=\"".htmlspecialchars($term['val'])."\"/>\n";
}
} // end if ( isset($term['attr']) )
} // end if isset($term['attr'])
if ( isset($term['cbr']) && (string)(int)$term['cbr'] == $term['cbr'] ) {
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][cbr]").'='.urlencode($term['cbr']);
$filter['sql'] .= ' '.str_repeat(')', $term['cbr']).' ';
$filter['sql'] .= ' '.str_repeat(')', $term['cbr']);
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[Query][terms][$i][cbr]\" value=\"".htmlspecialchars($term['cbr'])."\"/>\n";
}
} // end foreach term
@ -1347,6 +1347,9 @@ ZM\Logger::Debug("Term: " . print_r($term,true));
if ( $saveToSession ) {
$_SESSION['filter'] = $filter;
}
} else {
$filter['query'] = $querySep;
#.urlencode('filter[Query][terms]=[]');
} // end if terms
#if ( 0 ) {
@ -1359,7 +1362,7 @@ ZM\Logger::Debug("Term: " . print_r($term,true));
#$filter['sql'] .= ' LIMIT ' . validInt($filter['Query']['limit']);
#}
#}
}
} // end function parseFilter(&$filter, $saveToSession=false, $querySep='&amp;')
// Please note that the filter is passed in by copy, so you need to use the return value from this function.
//
@ -2615,4 +2618,12 @@ function html_radio($name, $values, $selected=null, $options=array(), $attrs=arr
return $html;
} # end sub html_radio
function random_colour() {
return '#'.
str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT).
str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT).
str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT);
}
?>

View File

@ -274,7 +274,7 @@ class Logger {
}
}
}
return( $this->databaseLevel );
return $this->databaseLevel;
}
public function fileLevel( $fileLevel ) {
@ -288,7 +288,7 @@ class Logger {
$this->openFile();
}
}
return( $this->fileLevel );
return $this->fileLevel;
}
public function weblogLevel( $weblogLevel ) {
@ -303,7 +303,7 @@ class Logger {
$this->weblogLevel = $weblogLevel;
}
}
return( $this->weblogLevel );
return $this->weblogLevel;
}
public function syslogLevel( $syslogLevel ) {
@ -317,30 +317,31 @@ class Logger {
$this->openSyslog();
}
}
return( $this->syslogLevel );
return $this->syslogLevel;
}
private function openSyslog() {
openlog( $this->id, LOG_PID|LOG_NDELAY, LOG_LOCAL1 );
openlog($this->id, LOG_PID|LOG_NDELAY, LOG_LOCAL1);
}
private function closeSyslog() {
closelog();
}
private function logFile( $logFile ) {
if ( preg_match( '/^(.+)\+$/', $logFile, $matches ) )
private function logFile($logFile) {
if ( preg_match('/^(.+)\+$/', $logFile, $matches) ) {
$this->logFile = $matches[1].'.'.getmypid();
else
} else {
$this->logFile = $logFile;
}
}
private function openFile() {
if ( !$this->useErrorLog ) {
if ( $this->logFd = fopen( $this->logFile, 'a+' ) ) {
if ( strnatcmp( phpversion(), '5.2.0' ) >= 0 ) {
if ( $this->logFd = fopen($this->logFile, 'a+') ) {
if ( strnatcmp(phpversion(), '5.2.0') >= 0 ) {
$error = error_get_last();
trigger_error( "Can't open log file '$logFile': ".$error['message'].' @ '.$error['file'].'/'.$error['line'], E_USER_ERROR );
trigger_error("Can't open log file '$logFile': ".$error['message'].' @ '.$error['file'].'/'.$error['line'], E_USER_ERROR);
}
$this->fileLevel = self::NOLOG;
}
@ -349,73 +350,83 @@ class Logger {
private function closeFile() {
if ( $this->logFd )
fclose( $this->logFd );
fclose($this->logFd);
}
public function logPrint( $level, $string, $file=NULL, $line=NULL ) {
if ( $level <= $this->effectiveLevel ) {
$string = preg_replace( '/[\r\n]+$/', '', $string );
$code = self::$codes[$level];
if ( $level > $this->effectiveLevel ) {
return;
}
$time = gettimeofday();
$message = sprintf( '%s.%06d %s[%d].%s [%s]', strftime( '%x %H:%M:%S', $time['sec'] ), $time['usec'], $this->id, getmypid(), $code, $string );
$string = preg_replace('/[\r\n]+$/', '', $string);
$code = self::$codes[$level];
if ( is_null($file) ) {
if ( $this->useErrorLog || $this->databaseLevel > self::NOLOG ) {
$backTrace = debug_backtrace();
$file = $backTrace[1]['file'];
$line = $backTrace[1]['line'];
if ( $this->hasTerm )
$rootPath = getcwd();
else
$rootPath = $_SERVER['DOCUMENT_ROOT'];
$file = preg_replace( '/^'.addcslashes($rootPath,'/').'\/?/', '', $file );
}
}
$time = gettimeofday();
$message = sprintf('%s.%06d %s[%d].%s [%s] [%s]',
strftime('%x %H:%M:%S', $time['sec']), $time['usec'],
$this->id, getmypid(), $code, $_SERVER['REMOTE_ADDR'], $string);
if ( $this->useErrorLog )
$message .= ' at '.$file.' line '.$line;
else
$message = $message;
if ( $level <= $this->termLevel )
if ( is_null($file) ) {
if ( $this->useErrorLog || ($this->databaseLevel > self::NOLOG) ) {
$backTrace = debug_backtrace();
$file = $backTrace[1]['file'];
$line = $backTrace[1]['line'];
if ( $this->hasTerm )
print( $message."\n" );
$rootPath = getcwd();
else
print( preg_replace( "/\n/", '<br/>', htmlspecialchars($message) ).'<br/>' );
if ( $level <= $this->fileLevel )
if ( $this->useErrorLog ) {
if ( !error_log( $message."\n", 3, $this->logFile ) ) {
if ( strnatcmp( phpversion(), '5.2.0' ) >= 0 ) {
$error = error_get_last();
trigger_error( "Can't write to log file '".$this->logFile."': ".$error['message'].' @ '.$error['file'].'/'.$error['line'], E_USER_ERROR );
}
}
} elseif ( $this->logFd ) {
fprintf( $this->logFd, $message."\n" );
}
$message = $code.' ['.$string.']';
if ( $level <= $this->syslogLevel )
syslog( self::$syslogPriorities[$level], $message );
if ( $level <= $this->databaseLevel ) {
try {
global $dbConn;
$sql = 'INSERT INTO Logs ( TimeKey, Component, Pid, Level, Code, Message, File, Line ) values ( ?, ?, ?, ?, ?, ?, ?, ? )';
$stmt = $dbConn->prepare( $sql );
$result = $stmt->execute( array( sprintf( '%d.%06d', $time['sec'], $time['usec'] ), $this->id, getmypid(), $level, $code, $string, $file, $line ) );
} catch(PDOException $ex) {
$this->databaseLevel = self::NOLOG;
Error("Can't write log entry '$sql': ". $ex->getMessage());
}
$rootPath = $_SERVER['DOCUMENT_ROOT'];
$file = preg_replace('/^'.addcslashes($rootPath,'/').'\/?/', '', $file);
}
// This has to be last as trigger_error can be fatal
if ( $level <= $this->weblogLevel ) {
if ( $this->useErrorLog )
error_log( $message, 0 );
else
trigger_error( $message, self::$phpErrorLevels[$level] );
}
if ( $this->useErrorLog ) {
$message .= ' at '.$file.' line '.$line;
} else {
$message = $message;
}
if ( $level <= $this->termLevel ) {
if ( $this->hasTerm )
print($message."\n");
else
print(preg_replace("/\n/", '<br/>', htmlspecialchars($message)).'<br/>');
}
if ( $level <= $this->fileLevel ) {
if ( $this->useErrorLog ) {
if ( !error_log($message."\n", 3, $this->logFile) ) {
if ( strnatcmp(phpversion(), '5.2.0') >= 0 ) {
$error = error_get_last();
trigger_error("Can't write to log file '".$this->logFile."': ".$error['message'].' @ '.$error['file'].'/'.$error['line'], E_USER_ERROR);
}
}
} else if ( $this->logFd ) {
fprintf($this->logFd, $message."\n");
}
}
$message = $code.' ['.$string.']';
if ( $level <= $this->syslogLevel )
syslog( self::$syslogPriorities[$level], $message );
if ( $level <= $this->databaseLevel ) {
try {
global $dbConn;
$sql = 'INSERT INTO `Logs` ( `TimeKey`, `Component`, `ServerId`, `Pid`, `Level`, `Code`, `Message`, `File`, `Line` ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )';
$stmt = $dbConn->prepare($sql);
$result = $stmt->execute(array(sprintf('%d.%06d', $time['sec'], $time['usec']), $this->id,
(defined('ZM_SERVER_ID') ? ZM_SERVER_ID : null), getmypid(), $level, $code, $string, $file, $line));
} catch(PDOException $ex) {
$this->databaseLevel = self::NOLOG;
Error("Can't write log entry '$sql': ". $ex->getMessage());
}
}
// This has to be last as trigger_error can be fatal
if ( $level <= $this->weblogLevel ) {
if ( $this->useErrorLog ) {
error_log($message, 0);
} else {
trigger_error($message, self::$phpErrorLevels[$level]);
}
}
}

View File

@ -152,8 +152,6 @@ if (
setcookie('zmCSS', $css, time()+3600*24*30*12*10);
}
# Only one request can open the session file at a time, so let's close the session here to improve concurrency.
# Any file/page that sets session variables must re-open it.
require_once('includes/lang.php');
@ -186,6 +184,8 @@ if ( isset($_REQUEST['request']) )
$request = detaintPath($_REQUEST['request']);
require_once('includes/auth.php');
# Only one request can open the session file at a time, so let's close the session here to improve concurrency.
# Any file/page that sets session variables must re-open it.
session_write_close();
foreach ( getSkinIncludes('skin.php') as $includeFile ) {
@ -242,6 +242,12 @@ if ( ZM_OPT_USE_AUTH and (!isset($user)) and ($view != 'login') and ($view != 'n
ZM\Logger::Debug('Redirecting to login');
$view = 'none';
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=login';
if ( ! $request ) {
zm_session_start();
$_SESSION['postLoginQuery'] = $_SERVER['QUERY_STRING'];
ZM\Error("postLoginQuery " . $_SESSION['postLoginQuery']);
session_write_close();
}
$request = null;
} else if ( ZM_SHOW_PRIVACY && ($view != 'privacy') && ($view != 'options') && (!$request) && canEdit('System') ) {
$view = 'none';

View File

@ -982,6 +982,14 @@ $OLANG = array(
"loglevel=debug" Set verbosity of FFmpeg (quiet, panic, fatal, error, warning, info, verbose, debug)
'
),
'OPTIONS_DECODERHWACCELNAME' => array(
'Help' => '
This is equivalent to the ffmpeg -hwaccel command line option. With intel graphics support, use "vaapi". For NVIDIA cuda support use "cuda". To check for support, run ffmpeg -hwaccels on the command line.'
),
'OPTIONS_DECODERHWACCELDEVICE' => array(
'Help' => '
This is equivalent to the ffmpeg -hwaccel_device command line option. You should only have to specify this if you have multiple GPUs. A typical value for Intel VAAPI would be /dev/dri/renderD128.'
),
'OPTIONS_RTSPTrans' => array(
'Help' => '
This sets the RTSP Transport Protocol for FFmpeg.~~

View File

@ -0,0 +1,4 @@
input[type="number"] {
width: 70px;
}

View File

@ -1,3 +1,9 @@
#content table.major .colCanMove, #content table.major .colCanZoom, #content table.major .colCanFocus, #content table.major .colCanIris, #content table.major .colCanWhiteBal, #content table.major .colHasPresets {
#content table.major .colCanMove,
#content table.major .colCanZoom,
#content table.major .colCanFocus,
#content table.major .colCanIris,
#content table.major .colCanWhiteBal,
#content table.major .colHasPresets {
text-align: center;
}

View File

@ -9,6 +9,10 @@
width: 100%;
}
textarea,
input[name="newMonitor[Name]"] {
width: 100%;
}
input[name="newMonitor[Width]"],
input[name="newMonitor[Height]"] {
width: 80px;

View File

@ -113,17 +113,17 @@ function exportEventDetail($event, $exportFrames, $exportImages) {
<table id="eventDetail">
<tr><th scope="row"><?php echo translate('Id') ?></th><td><?php echo $event->Id() ?></td></tr>
<tr><th scope="row"><?php echo translate('Name') ?></th><td><?php echo validHtmlStr($event->Name()) ?></td></tr>
<tr><th scope="row"><?php echo translate('Monitor') ?></th><td><?php echo validHtmlStr($event->MonitorName()) ?> (<?php echo $event->MonitorId() ?>)</td></tr>
<tr><th scope="row"><?php echo translate('Monitor') ?></th><td><?php echo validHtmlStr($event->Monitor()->Name()) ?> (<?php echo $event->MonitorId() ?>)</td></tr>
<tr><th scope="row"><?php echo translate('Cause') ?></th><td><?php echo validHtmlStr($event->Cause()) ?></td></tr>
<tr><th scope="row"><?php echo translate('Notes') ?></th><td><?php echo validHtmlStr($event->Notes()) ?></td></tr>
<tr><th scope="row"><?php echo translate('Time') ?></th><td><?php echo strftime( STRF_FMT_DATETIME_SHORTER, strtotime($event->StartTime()) ) ?></td></tr>
<tr><th scope="row"><?php echo translate('Time') ?></th><td><?php echo strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->StartTime())) ?></td></tr>
<tr><th scope="row"><?php echo translate('Duration') ?></th><td><?php echo $event->Length() ?></td></tr>
<tr><th scope="row"><?php echo translate('Frames') ?></th><td><?php echo $event->Frames() ?></td></tr>
<tr><th scope="row"><?php echo translate('AttrAlarmFrames') ?></th><td><?php echo $event->AlarmFrames() ?></td></tr>
<tr><th scope="row"><?php echo translate('AttrTotalScore') ?></th><td><?php echo $event->TotScore() ?></td></tr>
<tr><th scope="row"><?php echo translate('AttrAvgScore') ?></th><td><?php echo $event->AvgScore() ?></td></tr>
<tr><th scope="row"><?php echo translate('AttrMaxScore') ?></th><td><?php echo $event->MaxScore() ?></td></tr>
<tr><th scope="row"><?php echo translate('Archived') ?></th><td><?php echo $event->Archived()?translate('Yes'):translate('No') ?></td></tr>
<tr><th scope="row"><?php echo translate('Archived') ?></th><td><?php echo translate($event->Archived()?'Yes':'No') ?></td></tr>
</table>
</div>
</div>
@ -226,13 +226,13 @@ function exportEventImages($event, $exportDetail, $exportFrames, $myfilelist) {
?>
<body>
<style>
*.horizontal_track {background-color: #bbb;width: <?php echo$event->Width()?>px;line-height: 0px;font-size: 0px;text-align: left;padding: 4px;border: 1px solid;border-color: #ddd #999 #999 #ddd;}
*.horizontal_slider {background-color: #666;width: 16px;height: 8px;position: relative;z-index: 2;line-height: 0;margin: 0;border: 2px solid;border-color: #999 #333 #333 #999;}
*.horizontal_slit {background-color: #333;width: <?php echo($event->Width()-10)?>px;height: 2px;margin: 4px 4px 2px 4px;line-height: 0;position: absolute;z-index: 1;border: 1px solid;border-color: #999 #ddd #ddd #999;}
*.vertical_track {background-color: #bbb;padding: 3px 5px 15px 5px;border: 1px solid;border-color: #ddd #999 #999 #ddd;}
*.vertical_slider {background-color: #666;width: 18px;height: 8px;font: 0px;text-align: left;line-height: 0px;position: relative;z-index: 1;border: 2px solid;border-color: #999 #333 #333 #999;}
*.vertical_slit {background-color: #000;width: 2px;height: 100px;position: absolute;margin: 4px 10px 4px 10px;padding: 4px 0 1px 0;line-height: 0;font-size: 0;border: 1px solid;border-color: #666 #ccc #ccc #666;}
*.display_holder {background-color: #bbb;color: #fff;width: 34px;height: 20px;text-align: right;padding: 0;border: 1px solid;border-color: #ddd #999 #999 #ddd;}
.horizontal_track {background-color: #bbb;width: <?php echo $event->Width()?>px;line-height: 0px;font-size: 0px;text-align: left;padding: 4px;border: 1px solid;border-color: #ddd #999 #999 #ddd;}
.horizontal_slider {background-color: #666;width: 16px;height: 8px;position: relative;z-index: 2;line-height: 0;margin: 0;border: 2px solid;border-color: #999 #333 #333 #999;}
.horizontal_slit {background-color: #333;width: <?php echo($event->Width()-10)?>px;height: 2px;margin: 4px 4px 2px 4px;line-height: 0;position: absolute;z-index: 1;border: 1px solid;border-color: #999 #ddd #ddd #999;}
.vertical_track {background-color: #bbb;padding: 3px 5px 15px 5px;border: 1px solid;border-color: #ddd #999 #999 #ddd;}
.vertical_slider {background-color: #666;width: 18px;height: 8px;font: 0px;text-align: left;line-height: 0px;position: relative;z-index: 1;border: 2px solid;border-color: #999 #333 #333 #999;}
.vertical_slit {background-color: #000;width: 2px;height: 100px;position: absolute;margin: 4px 10px 4px 10px;padding: 4px 0 1px 0;line-height: 0;font-size: 0;border: 1px solid;border-color: #666 #ccc #ccc #666;}
.display_holder {background-color: #bbb;color: #fff;width: 34px;height: 20px;text-align: right;padding: 0;border: 1px solid;border-color: #ddd #999 #999 #ddd;}
.value_display {background-color: #bbb;color: #333;width: 30px;margin: 0 2px;text-align: right;font-size: 8pt;font-face: verdana, arial, helvetica, sans-serif;font-weight: bold;line-height: 12px;border: 0;cursor: default;}
</style>
@ -247,7 +247,7 @@ function exportEventImages($event, $exportDetail, $exportFrames, $myfilelist) {
if ( $Monitor->VideoWriter() == '2' ) {
# Passthrough
$Rotation = $event->Orientation();
if ( in_array($event->Orientation(),array('90','270')) )
if ( in_array($event->Orientation(),array('ROTATE_90','ROTATE_270')) )
$Zoom = $event->Height()/$event->Width();
}
?>
@ -280,7 +280,7 @@ function exportEventImages($event, $exportDetail, $exportFrames, $myfilelist) {
<div align="center"><div class="horizontal_track">
<div class="horizontal_slit">&nbsp;</div>
<div class="horizontal_slider" id="imageslider_id" style="left: 0px;"
onmousedown="slide(event,'horizontal', <?php echo($event->Width()-20)?>, 1, <?php echo$listcount?>, <?php echo$listcount?>,0, 'imageslider_display_id');">&nbsp;</div>
onmousedown="slide(event,'horizontal', <?php echo($event->Width()-20)?>, 1, <?php echo $listcount?>, <?php echo $listcount?>,0, 'imageslider_display_id');">&nbsp;</div>
</div>
</div>
<div align="center"><div class="display_holder"><input id="imageslider_display_id" class="value_display" type="text" value="0" onfocus="blur(this);"/></div></div>
@ -618,10 +618,10 @@ function exportEventImagesMaster($eids) {
<body>
<h2><?php echo translate('Images') ?> Master</h2>
<?php
// TODO: Should use find to make this 1 db query
foreach ($eids as $eid) {
$events = ZM\Event::find(array('Id'=>$eids));
foreach ($events as $event) {
//get monitor id and event id
$event = new ZM\Event($eid);
$eventMonitorId[$eid] = $event->MonitorId();
$eventPath[$eid] = $event->Relative_Path();
}
@ -653,20 +653,18 @@ function exportEventImagesMaster($eids) {
<div class="tab_content" id="all">
<h2> All </h2>
<?php
foreach($eids as $eid) {
$Event = new ZM\Event($eid);
eventlist_html($Event);
} # end foreach event id
foreach($events as $event) {
eventlist_html($event);
} # end foreach event
?>
</div>
<?php
foreach ($monitors as $monitor_id) {
echo "<div class=\"tab_content\" id=\"tab$monitor_id\">";
echo '<h2>Monitor: ' . $monitorNames[$monitor_id] . ' </h2>';
foreach ( $eids as $eid ) {
$Event = new ZM\Event($eid);
if ( $Event->MonitorId() == $monitor_id ) {
eventlist_html($Event);
foreach ( $events as $event ) {
if ( $event->MonitorId() == $monitor_id ) {
eventlist_html($event);
} # end if its the right monitor
} # end foreach event
echo '</div>';
@ -780,7 +778,7 @@ function exportFileList($event, $exportDetail, $exportFrames, $exportImages, $ex
}
fwrite($fp, exportEventDetail($event, $exportFrames, $exportImages));
fclose($fp);
$exportFileList[$file] = $event->Id().'/'.$file;
$exportFileList[$file] = $file;
}
if ( $exportFrames ) {
$file = 'zmEventFrames.html';
@ -789,7 +787,7 @@ function exportFileList($event, $exportDetail, $exportFrames, $exportImages, $ex
}
fwrite($fp, exportEventFrames($event, $exportDetail, $exportImages));
fclose($fp);
$exportFileList[$file] = $event->Id().'/'.$file;
$exportFileList[$file] = $file;
}
if ( $exportImages ) {
@ -797,7 +795,7 @@ function exportFileList($event, $exportDetail, $exportFrames, $exportImages, $ex
$myfilelist = array();
foreach ( $files as $file ) {
if ( preg_match('/-(?:capture|analyse).jpg$/', $file ) ) {
$myfilelist[$file] = $exportFileList[$file] = $event->Id().'/'.$file;
$myfilelist[$file] = $exportFileList[$file] = $file;
} else {
$filesLeft[$file] = $file;
}
@ -806,12 +804,12 @@ function exportFileList($event, $exportDetail, $exportFrames, $exportImages, $ex
// create an image slider
if ( !empty($myfilelist) ) {
$file = $event->Id().'/zmEventImages.html';
$file = 'zmEventImages.html';
if ( !($fp = fopen($file, 'w')) )
ZM\Fatal("Can't open event images export file '$file'");
fwrite($fp, exportEventImages($event, $exportDetail, $exportFrames, $myfilelist));
fclose($fp);
$exportFileList[$file] = $event->Id().'/'.$file;
$exportFileList[$file] = $file;
}
} # end if exportImages
@ -819,7 +817,7 @@ function exportFileList($event, $exportDetail, $exportFrames, $exportImages, $ex
$filesLeft = array();
foreach ( $files as $file ) {
if ( preg_match('/\.(?:mpg|mpeg|mov|swf|mp4|mkv|avi|asf|3gp)$/', $file) ) {
$exportFileList[$file] = $event->Id().'/'.$file;
$exportFileList[$file] = $file;
} else {
$filesLeft[$file] = $file;
}
@ -829,7 +827,7 @@ function exportFileList($event, $exportDetail, $exportFrames, $exportImages, $ex
if ( $exportMisc ) {
foreach ( $files as $file ) {
$exportFileList[$file] = $event->Id().'/'.$file;
$exportFileList[$file] = $file;
}
$files = array();
}
@ -850,10 +848,10 @@ function exportEvents(
) {
if ( !canView('Events') ) {
ZM\Error("You do not have permission to view events.");
ZM\Error('You do not have permission to view events.');
return false;
} else if ( empty($eids) ) {
ZM\Error("Attempt to export an empty list of events.");
ZM\Error('Attempt to export an empty list of events.');
return false;
}
@ -863,23 +861,22 @@ function exportEvents(
}
# Ensure that we are going to be able to do this.
if ( ! file_exists(ZM_DIR_EXPORTS) ) {
if ( ! mkdir(ZM_DIR_EXPORTS) ) {
ZM\Fatal("Can't create exports dir at '".ZM_DIR_EXPORTS."'");
}
if ( ! ( mkdir(ZM_DIR_EXPORTS) or file_exists(ZM_DIR_EXPORTS) ) ) {
ZM\Fatal('Can\'t create exports dir at \''.ZM_DIR_EXPORTS.'\'');
}
chmod(ZM_DIR_EXPORTS, 0700);
$export_dir = ZM_DIR_EXPORTS.'/zmExport_'.$connkey;
# Ensure that we are going to be able to do this.
if ( ! file_exists($export_dir) ) {
if ( ! mkdir($export_dir) ) {
ZM\Fatal("Can't create exports dir at '$export_dir'");
} else {
ZM\Logger::Debug("Successfully created dir '$export_dir'");
}
if ( ! ( mkdir($export_dir) or file_exists($export_dir) ) ) {
ZM\Fatal("Can't create exports dir at '$export_dir'");
} else {
ZM\Logger::Debug("Successfully created dir '$export_dir'");
}
if ( !chdir($export_dir) )
chmod($export_dir, 0700);
if ( !chdir($export_dir) ) {
ZM\Fatal("Can't chdir to $export_dir");
}
$export_root = 'zmExport';
$export_listFile = 'zmFileList.txt';
@ -889,27 +886,30 @@ function exportEvents(
if ( !is_array($eids) ) {
$eids = array($eids);
}
ZM\Logger::Debug("Eids: " . print_r($eids,true));
ZM\Logger::Debug('Eids: ' . print_r($eids,true));
foreach ( $eids as $eid ) {
$event = new ZM\Event($eid);
$event_dir = $export_dir.'/'.$event->Id();
if ( !mkdir($event_dir) )
if ( !(mkdir($event_dir) or file_exists($event_dir) ) ) {
ZM\Error("Can't mkdir $event_dir");
}
$event_exportFileList = exportFileList($event, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc);
ZM\Logger::Debug("File list for event $eid " . print_r($event_exportFileList, true));
$exportFileList = array_merge($exportFileList,$event_exportFileList);
foreach ( $event_exportFileList as $file ) {
if ( preg_match('/\.html$/', $file ) )
if ( preg_match('/\.html$/', $file) )
continue;
ZM\Logger::Debug('cp -as '.$event->Path().'/../'.$file.' '.$export_dir.'/'.$file);
exec('cp -as '.$event->Path().'/../'.$file.' '.$export_dir.'/'.$file);
#exec('cp -as '.$event->Path().'/../'.$file.' '.$export_dir.'/'.$file, $output, $return);
$cmd = 'cp -as '.$event->Path().'/'.$file.' '.$export_dir.'/'.$event->Id().'/'.$file. ' 2>&1';
exec($cmd, $output, $return);
ZM\Logger::Debug($cmd.' return code: '.$return.' output: '.print_r($output,true));
}
}
} # end foreach event
// create an master image
if ( $exportImages ) {
if ( !symlink(ZM_PATH_WEB.'/'.ZM_SKIN_PATH.'/js/jquery.js', $export_dir.'/jquery.js') )
ZM\Error("Failed linking jquery.js");
ZM\Error('Failed linking jquery.js');
//if ( !symlink(ZM_PATH_WEB.'/'.ZM_SKIN_PATH.'/js/video.js', $export_dir.'/video.js') )
//Error("Failed linking video.js");
@ -940,6 +940,8 @@ function exportEvents(
$archive = '';
if ( $exportFormat == 'tar' ) {
$archive = ZM_DIR_EXPORTS.'/'.$export_root.($connkey?'_'.$connkey:'').'.tar';
$version = shell_exec('tar -v');
$command = 'tar --create --dereference';
if ( $exportCompressed ) {
$archive .= '.gz';
@ -947,8 +949,11 @@ function exportEvents(
$exportFormat .= '.gz';
}
if ( $exportStructure == 'flat' ) {
//strip file paths if we
$command .= " --xform='s#^.+/##x'";
if (preg_match("/BSD/i", $version)) {
$command .= " -s '#^.*/##'";
} else {
$command .= " --xform='s#^.+/##x'";
}
}
$command .= ' --file='.escapeshellarg($archive);
} elseif ( $exportFormat == 'zip' ) {
@ -960,12 +965,12 @@ function exportEvents(
@unlink($archive);
$command .= ' zmExport_' . $connkey.'/';
ZM\Logger::Debug("Command is $command");
exec($command, $output, $status);
if ( $status ) {
ZM\Error("Command '$command' returned with status $status");
if ( isset($output[0]) )
ZM\Error("First line of output is '".$output[0]."'");
if ( isset($output[0]) ) {
ZM\Error('First line of output is \''.$output[0].'\'');
}
return false;
}

View File

@ -30,7 +30,6 @@ function xhtmlHeaders($file, $title) {
$skinCssPhpFile = getSkinFile('css/'.$css.'/skin.css.php');
$skinJsFile = getSkinFile('js/skin.js');
$skinJsPhpFile = getSkinFile('js/skin.js.php');
$cssJsFile = getSkinFile('js/'.$css.'.js');
@ -84,7 +83,6 @@ echo output_link_if_exists( array(
'css/base/views/'.$basename.'.css',
'js/dateTimePicker/jquery-ui-timepicker-addon.css',
'js/jquery-ui-1.12.1/jquery-ui.structure.min.css',
#'js/jquery-ui-1.12.1/jquery-ui.theme.min.css',
)
);
if ( $css != 'base' )
@ -95,8 +93,9 @@ if ( $css != 'base' )
)
);
?>
<link rel="stylesheet" href="skins/classic/js/jquery-ui-1.12.1/jquery-ui.theme.min.css" type="text/css"/>
<!--Chosen can't be cache-busted because it loads sprites by relative path-->
<!--Chosen can't be cache-busted because it loads sprites by relative path-->
<link rel="stylesheet" href="skins/classic/js/chosen/chosen.min.css" type="text/css"/>
<?php
if ( $basename == 'watch' ) {
@ -188,7 +187,9 @@ if ( $css != 'base' )
} else {
?>
<script src="<?php echo cache_bust('skins/classic/js/base.js') ?>"></script>
<?php } ?>
<?php }
$skinJsFile = getSkinFile('js/skin.js');
?>
<script src="<?php echo cache_bust($skinJsFile) ?>"></script>
<script src="<?php echo cache_bust('js/logger.js')?>"></script>
<?php
@ -290,12 +291,12 @@ if ( $user and $user['Username'] ) {
# zmaudit can clean the logs, but if we aren't running it, then we should clean them regularly
if ( preg_match('/^\d+$/', ZM_LOG_DATABASE_LIMIT) ) {
# Number of lines, instead of an interval
$rows = dbFetchOne('SELECT Count(*) AS Rows FROM Logs', 'Rows');
$rows = dbFetchOne('SELECT Count(*) AS `Rows` FROM `Logs`', 'Rows');
if ( $rows > ZM_LOG_DATABASE_LIMIT ) {
dbQuery('DELETE low_priority FROM Logs ORDER BY TimeKey ASC LIMIT ?', array($rows - ZM_LOG_DATABASE_LIMIT));
dbQuery('DELETE low_priority FROM `Logs` ORDER BY `TimeKey` ASC LIMIT ?', array($rows - ZM_LOG_DATABASE_LIMIT));
}
} else if ( preg_match('/^\d\s*(hour|minute|day|week|month|year)$/', ZM_LOG_DATABASE_LIMIT, $matches) ) {
dbQuery('DELETE FROM Logs WHERE TimeKey < unix_timestamp( NOW() - interval '.ZM_LOG_DATABASE_LIMIT.') LIMIT 100');
dbQuery('DELETE FROM `Logs` WHERE `TimeKey` < unix_timestamp( NOW() - interval '.ZM_LOG_DATABASE_LIMIT.') LIMIT 100');
} else {
ZM\Error('Potentially invalid value for ZM_LOG_DATABASE_LIMIT: ' . ZM_LOG_DATABASE_LIMIT);
}

View File

@ -29,7 +29,7 @@ var popupSizes = {
'console': {'width': 750, 'height': 312},
'control': {'width': 480, 'height': 480},
'controlcaps': {'width': 780, 'height': 320},
'controlcap': {'width': 400, 'height': 400},
'controlcap': {'width': 600, 'height': 500},
'cycle': {'addWidth': 32, 'minWidth': 384, 'addHeight': 62},
'device': {'width': 260, 'height': 150},
'devices': {'width': 400, 'height': 240},

View File

@ -175,12 +175,13 @@ window.addEventListener("DOMContentLoaded", function onSkinDCL() {
});
// 'data-on-click' calls the global function in the attribute value with no arguments when a click happens.
document.querySelectorAll("a[data-on-click], button[data-on-click], input[data-on-click]").forEach(function attachOnClick(el) {
document.querySelectorAll("i[data-on-click], a[data-on-click], button[data-on-click], input[data-on-click]").forEach(function attachOnClick(el) {
var fnName = el.getAttribute("data-on-click");
if ( !window[fnName] ) {
console.error("Nothing found to bind to " + fnName + " on element " + el.name);
return;
}
el.onclick = function() {
window[fnName]();
};

View File

@ -187,7 +187,8 @@ getBodyTopHTML();
<button type="button" name="cloneBtn" data-on-click-this="cloneMonitor"
<?php echo (canEdit('Monitors') && !$user['MonitorIds']) ? '' : ' disabled="disabled"' ?>
style="display:none;">
<i class="material-icons md-18">copy</i>
<i class="material-icons md-18">content_copy</i>
<!--content_copy used instead of file_copy as there is a bug in material-icons -->
&nbsp;<?php echo translate('CloneMonitor') ?>
</button>
<button type="button" name="editBtn" data-on-click-this="editMonitor" disabled="disabled">
@ -200,7 +201,7 @@ getBodyTopHTML();
</button>
<button type="button" name="selectBtn" data-on-click-this="selectMonitor" disabled="disabled">
<i class="material-icons md-18">view_list</i>
&nbsp;<?php echo translate('Select')?>
&nbsp;<?php echo translate('Select') ?>
</button>
<?php
ob_start();

View File

@ -18,40 +18,31 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
if ( !canEdit( 'Control' ) )
{
$view = "error";
return;
if ( !canEdit('Control') ) {
$view = 'error';
return;
}
$tabs = array();
$tabs["main"] = translate('Main');
$tabs["move"] = translate('Move');
$tabs["pan"] = translate('Pan');
$tabs["tilt"] = translate('Tilt');
$tabs["zoom"] = translate('Zoom');
$tabs["focus"] = translate('Focus');
$tabs["white"] = translate('White');
$tabs["iris"] = translate('Iris');
$tabs["presets"] = translate('Presets');
$tabs['main'] = translate('Main');
$tabs['move'] = translate('Move');
$tabs['pan'] = translate('Pan');
$tabs['tilt'] = translate('Tilt');
$tabs['zoom'] = translate('Zoom');
$tabs['focus'] = translate('Focus');
$tabs['gain'] = translate('Gain');
$tabs['white'] = translate('White');
$tabs['iris'] = translate('Iris');
$tabs['presets'] = translate('Presets');
if ( isset($_REQUEST['tab']) )
$tab = validHtmlStr($_REQUEST['tab']);
else
$tab = "main";
$tab = isset($_REQUEST['tab']) ? validHtmlStr($_REQUEST['tab']) :'main';
if ( isset( $_REQUEST['newControl'] ) )
{
if ( isset($_REQUEST['newControl']) ) {
$newControl = $_REQUEST['newControl'];
}
else
{
if ( !empty($_REQUEST['cid']) )
{
$control = dbFetchOne( 'SELECT * FROM Controls WHERE Id = ?', NULL, array($_REQUEST['cid'] ) );
}
else
{
} else {
if ( !empty($_REQUEST['cid']) ) {
$control = dbFetchOne('SELECT * FROM Controls WHERE Id = ?', NULL, array($_REQUEST['cid']));
} else {
$control = array(
'Name' => translate('New'),
'Type' => "Local",
@ -166,16 +157,12 @@ xhtmlHeaders(__FILE__, translate('ControlCap')." - ".$newControl['Name'] );
<div id="content">
<ul class="tabList">
<?php
foreach ( $tabs as $name=>$value )
{
if ( $tab == $name )
{
foreach ( $tabs as $name=>$value ) {
if ( $tab == $name ) {
?>
<li class="active"><?php echo $value ?></li>
<?php
}
else
{
} else {
?>
<li><a href="#" data-tab-name="<?php echo $name ?>"><?php echo $value ?></a></li>
<?php
@ -190,8 +177,7 @@ foreach ( $tabs as $name=>$value )
<input type="hidden" name="action" value="controlcap"/>
<input type="hidden" name="cid" value="<?php echo requestVar('cid') ?>"/>
<?php
if ( $tab != 'main' )
{
if ( $tab != 'main' ) {
?>
<input type="hidden" name="newControl[Name]" value="<?php echo validHtmlStr($newControl['Name']) ?>"/>
<input type="hidden" name="newControl[Type]" value="<?php echo validHtmlStr($newControl['Type']) ?>"/>
@ -201,8 +187,7 @@ if ( $tab != 'main' )
<input type="hidden" name="newControl[CanReset]" value="<?php echo !empty($newControl['CanReset']) ?>"/>
<?php
}
if ( $tab != 'move' )
{
if ( $tab != 'move' ) {
?>
<input type="hidden" name="newControl[CanMove]" value="<?php echo !empty($newControl['CanMove']) ?>"/>
<input type="hidden" name="newControl[CanMoveDiag]" value="<?php echo !empty($newControl['CanMoveDiag']) ?>"/>
@ -212,8 +197,7 @@ if ( $tab != 'move' )
<input type="hidden" name="newControl[CanMoveCon]" value="<?php echo !empty($newControl['CanMoveCon']) ?>"/>
<?php
}
if ( $tab != 'pan' )
{
if ( $tab != 'pan' ) {
?>
<input type="hidden" name="newControl[CanPan]" value="<?php echo !empty($newControl['CanPan']) ?>"/>
<input type="hidden" name="newControl[MinPanRange]" value="<?php echo validHtmlStr($newControl['MinPanRange']) ?>"/>
@ -227,8 +211,7 @@ if ( $tab != 'pan' )
<input type="hidden" name="newControl[TurboPanSpeed]" value="<?php echo validHtmlStr($newControl['TurboPanSpeed']) ?>"/>
<?php
}
if ( $tab != 'tilt' )
{
if ( $tab != 'tilt' ) {
?>
<input type="hidden" name="newControl[CanTilt]" value="<?php echo !empty($newControl['CanTilt']) ?>"/>
<input type="hidden" name="newControl[MinTiltRange]" value="<?php echo validHtmlStr($newControl['MinTiltRange']) ?>"/>
@ -242,8 +225,7 @@ if ( $tab != 'tilt' )
<input type="hidden" name="newControl[TurboTiltSpeed]" value="<?php echo validHtmlStr($newControl['TurboTiltSpeed']) ?>"/>
<?php
}
if ( $tab != 'zoom' )
{
if ( $tab != 'zoom' ) {
?>
<input type="hidden" name="newControl[CanZoom]" value="<?php echo !empty($newControl['CanZoom']) ?>"/>
<input type="hidden" name="newControl[CanZoomAbs]" value="<?php echo !empty($newControl['CanZoomAbs']) ?>"/>
@ -258,8 +240,7 @@ if ( $tab != 'zoom' )
<input type="hidden" name="newControl[MaxZoomSpeed]" value="<?php echo validHtmlStr($newControl['MaxZoomSpeed']) ?>"/>
<?php
}
if ( $tab != 'focus' )
{
if ( $tab != 'focus' ) {
?>
<input type="hidden" name="newControl[CanFocus]" value="<?php echo !empty($newControl['CanFocus']) ?>"/>
<input type="hidden" name="newControl[CanAutoFocus]" value="<?php echo !empty($newControl['CanAutoFocus']) ?>"/>
@ -275,8 +256,7 @@ if ( $tab != 'focus' )
<input type="hidden" name="newControl[MaxFocusSpeed]" value="<?php echo validHtmlStr($newControl['MaxFocusSpeed']) ?>"/>
<?php
}
if ( $tab != 'iris' )
{
if ( $tab != 'iris' ) {
?>
<input type="hidden" name="newControl[CanIris]" value="<?php echo !empty($newControl['CanIris']) ?>"/>
<input type="hidden" name="newControl[CanAutoIris]" value="<?php echo !empty($newControl['CanAutoIris']) ?>"/>
@ -292,8 +272,7 @@ if ( $tab != 'iris' )
<input type="hidden" name="newControl[MaxIrisSpeed]" value="<?php echo validHtmlStr($newControl['MaxIrisSpeed']) ?>"/>
<?php
}
if ( $tab != 'gain' )
{
if ( $tab != 'gain' ) {
?>
<input type="hidden" name="newControl[CanGain]" value="<?php echo !empty($newControl['CanGain']) ?>"/>
<input type="hidden" name="newControl[CanAutoGain]" value="<?php echo !empty($newControl['CanAutoGain']) ?>"/>
@ -309,8 +288,7 @@ if ( $tab != 'gain' )
<input type="hidden" name="newControl[MaxGainSpeed]" value="<?php echo validHtmlStr($newControl['MaxGainSpeed']) ?>"/>
<?php
}
if ( $tab != 'white' )
{
if ( $tab != 'white' ) {
?>
<input type="hidden" name="newControl[CanWhite]" value="<?php echo !empty($newControl['CanWhite']) ?>"/>
<input type="hidden" name="newControl[CanAutoWhite]" value="<?php echo !empty($newControl['CanAutoWhite']) ?>"/>
@ -326,8 +304,7 @@ if ( $tab != 'white' )
<input type="hidden" name="newControl[MaxWhiteSpeed]" value="<?php echo validHtmlStr($newControl['MaxWhiteSpeed']) ?>"/>
<?php
}
if ( $tab != 'presets' )
{
if ( $tab != 'presets' ) {
?>
<input type="hidden" name="newControl[HasPresets]" value="<?php echo !empty($newControl['HasPresets']) ?>"/>
<input type="hidden" name="newControl[NumPresets]" value="<?php echo validHtmlStr($newControl['NumPresets']) ?>"/>
@ -336,19 +313,17 @@ if ( $tab != 'presets' )
<?php
}
?>
<table id="contentTable" class="major" cellspacing="0">
<table id="contentTable" class="major">
<tbody>
<?php
switch ( $tab )
{
case 'main' :
{
switch ( $tab ) {
case 'main' :
{
?>
<tr><th scope="row"><?php echo translate('Name') ?></th><td><input type="text" name="newControl[Name]" value="<?php echo validHtmlStr($newControl['Name']) ?>" size="24"/></td></tr>
<?php
$types = array( 'Local'=>translate('Local'), 'Remote'=>translate('Remote'), 'Ffmpeg'=>translate('Ffmpeg'), 'Libvlc'=>translate('Libvlc'), 'cURL'=>"cURL");
?>
<tr><th scope="row"><?php echo translate('Type') ?></th><td><?php echo buildSelect( "newControl[Type]", $types ); ?></td></tr>
<tr><th scope="row"><?php echo translate('Name') ?></th><td><input type="text" name="newControl[Name]" value="<?php echo validHtmlStr($newControl['Name']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('Type') ?></th><td><?php
$types = array( 'Local'=>translate('Local'), 'Remote'=>translate('Remote'), 'Ffmpeg'=>translate('Ffmpeg'), 'Libvlc'=>translate('Libvlc'), 'cURL'=>'cURL');
echo buildSelect('newControl[Type]', $types); ?></td></tr>
<tr><th scope="row"><?php echo translate('Protocol') ?></th><td><input type="text" name="newControl[Protocol]" value="<?php echo validHtmlStr($newControl['Protocol']) ?>" size="24"/></td></tr>
<tr><th scope="row"><?php echo translate('CanWake') ?></th><td><input type="checkbox" name="newControl[CanWake]" value="1"<?php if ( !empty($newControl['CanWake']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanSleep') ?></th><td><input type="checkbox" name="newControl[CanSleep]" value="1"<?php if ( !empty($newControl['CanSleep']) ) { ?> checked="checked"<?php } ?>/></td></tr>
@ -373,15 +348,15 @@ switch ( $tab )
{
?>
<tr><th scope="row"><?php echo translate('CanPan') ?></th><td><input type="checkbox" name="newControl[CanPan]" value="1"<?php if ( !empty($newControl['CanPan']) ) { ?> checked="checked"<?php } ?>></td></tr>
<tr><th scope="row"><?php echo translate('MinPanRange') ?></th><td><input type="text" name="newControl[MinPanRange]" value="<?php echo validHtmlStr($newControl['MinPanRange']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxPanRange') ?></th><td><input type="text" name="newControl[MaxPanRange]" value="<?php echo validHtmlStr($newControl['MaxPanRange']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinPanStep') ?></th><td><input type="text" name="newControl[MinPanStep]" value="<?php echo validHtmlStr($newControl['MinPanStep']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxPanStep') ?></th><td><input type="text" name="newControl[MaxPanStep]" value="<?php echo validHtmlStr($newControl['MaxPanStep']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinPanRange') ?></th><td><input type="number" name="newControl[MinPanRange]" value="<?php echo validHtmlStr($newControl['MinPanRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxPanRange') ?></th><td><input type="number" name="newControl[MaxPanRange]" value="<?php echo validHtmlStr($newControl['MaxPanRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinPanStep') ?></th><td><input type="number" name="newControl[MinPanStep]" value="<?php echo validHtmlStr($newControl['MinPanStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxPanStep') ?></th><td><input type="number" name="newControl[MaxPanStep]" value="<?php echo validHtmlStr($newControl['MaxPanStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasPanSpeed') ?></th><td><input type="checkbox" name="newControl[HasPanSpeed]" value="1"<?php if ( !empty($newControl['HasPanSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinPanSpeed') ?></th><td><input type="text" name="newControl[MinPanSpeed]" value="<?php echo validHtmlStr($newControl['MinPanSpeed']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxPanSpeed') ?></th><td><input type="text" name="newControl[MaxPanSpeed]" value="<?php echo validHtmlStr($newControl['MaxPanSpeed']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinPanSpeed') ?></th><td><input type="number" name="newControl[MinPanSpeed]" value="<?php echo validHtmlStr($newControl['MinPanSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxPanSpeed') ?></th><td><input type="number" name="newControl[MaxPanSpeed]" value="<?php echo validHtmlStr($newControl['MaxPanSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasTurboPan') ?></th><td><input type="checkbox" name="newControl[HasTurboPan]" value="1"<?php if ( !empty($newControl['HasTurboPan']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('TurboPanSpeed') ?></th><td><input type="text" name="newControl[TurboPanSpeed]" value="<?php echo validHtmlStr($newControl['TurboPanSpeed']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('TurboPanSpeed') ?></th><td><input type="number" name="newControl[TurboPanSpeed]" value="<?php echo validHtmlStr($newControl['TurboPanSpeed']) ?>"/></td></tr>
<?php
break;
}
@ -389,15 +364,15 @@ switch ( $tab )
{
?>
<tr><th scope="row"><?php echo translate('CanTilt') ?></th><td><input type="checkbox" name="newControl[CanTilt]" value="1"<?php if ( !empty($newControl['CanTilt']) ) { ?> checked="checked"<?php } ?>></td></tr>
<tr><th scope="row"><?php echo translate('MinTiltRange') ?></th><td><input type="text" name="newControl[MinTiltRange]" value="<?php echo validHtmlStr($newControl['MinTiltRange']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxTiltRange') ?></th><td><input type="text" name="newControl[MaxTiltRange]" value="<?php echo validHtmlStr($newControl['MaxTiltRange']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinTiltStep') ?></th><td><input type="text" name="newControl[MinTiltStep]" value="<?php echo validHtmlStr($newControl['MinTiltStep']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxTiltStep') ?></th><td><input type="text" name="newControl[MaxTiltStep]" value="<?php echo validHtmlStr($newControl['MaxTiltStep']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinTiltRange') ?></th><td><input type="number" name="newControl[MinTiltRange]" value="<?php echo validHtmlStr($newControl['MinTiltRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxTiltRange') ?></th><td><input type="number" name="newControl[MaxTiltRange]" value="<?php echo validHtmlStr($newControl['MaxTiltRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinTiltStep') ?></th><td><input type="number" name="newControl[MinTiltStep]" value="<?php echo validHtmlStr($newControl['MinTiltStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxTiltStep') ?></th><td><input type="number" name="newControl[MaxTiltStep]" value="<?php echo validHtmlStr($newControl['MaxTiltStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasTiltSpeed') ?></th><td><input type="checkbox" name="newControl[HasTiltSpeed]" value="1"<?php if ( !empty($newControl['HasTiltSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinTiltSpeed') ?></th><td><input type="text" name="newControl[MinTiltSpeed]" value="<?php echo validHtmlStr($newControl['MinTiltSpeed']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxTiltSpeed') ?></th><td><input type="text" name="newControl[MaxTiltSpeed]" value="<?php echo validHtmlStr($newControl['MaxTiltSpeed']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinTiltSpeed') ?></th><td><input type="number" name="newControl[MinTiltSpeed]" value="<?php echo validHtmlStr($newControl['MinTiltSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxTiltSpeed') ?></th><td><input type="number" name="newControl[MaxTiltSpeed]" value="<?php echo validHtmlStr($newControl['MaxTiltSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasTurboTilt') ?></th><td><input type="checkbox" name="newControl[HasTurboTilt]" value="1"<?php if ( !empty($newControl['HasTurboTilt']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('TurboTiltSpeed') ?></th><td><input type="text" name="newControl[TurboTiltSpeed]" value="<?php echo validHtmlStr($newControl['TurboTiltSpeed']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('TurboTiltSpeed') ?></th><td><input type="number" name="newControl[TurboTiltSpeed]" value="<?php echo validHtmlStr($newControl['TurboTiltSpeed']) ?>"/></td></tr>
<?php
break;
}
@ -408,13 +383,13 @@ switch ( $tab )
<tr><th scope="row"><?php echo translate('CanZoomAbs') ?></th><td><input type="checkbox" name="newControl[CanZoomAbs]" value="1"<?php if ( !empty($newControl['CanZoomAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanZoomRel') ?></th><td><input type="checkbox" name="newControl[CanZoomRel]" value="1"<?php if ( !empty($newControl['CanZoomRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanZoomCon') ?></th><td><input type="checkbox" name="newControl[CanZoomCon]" value="1"<?php if ( !empty($newControl['CanZoomCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinZoomRange') ?></th><td><input type="text" name="newControl[MinZoomRange]" value="<?php echo validHtmlStr($newControl['MinZoomRange']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxZoomRange') ?></th><td><input type="text" name="newControl[MaxZoomRange]" value="<?php echo validHtmlStr($newControl['MaxZoomRange']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinZoomStep') ?></th><td><input type="text" name="newControl[MinZoomStep]" value="<?php echo validHtmlStr($newControl['MinZoomStep']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxZoomStep') ?></th><td><input type="text" name="newControl[MaxZoomStep]" value="<?php echo validHtmlStr($newControl['MaxZoomStep']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinZoomRange') ?></th><td><input type="number" name="newControl[MinZoomRange]" value="<?php echo validHtmlStr($newControl['MinZoomRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxZoomRange') ?></th><td><input type="number" name="newControl[MaxZoomRange]" value="<?php echo validHtmlStr($newControl['MaxZoomRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinZoomStep') ?></th><td><input type="number" name="newControl[MinZoomStep]" value="<?php echo validHtmlStr($newControl['MinZoomStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxZoomStep') ?></th><td><input type="number" name="newControl[MaxZoomStep]" value="<?php echo validHtmlStr($newControl['MaxZoomStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasZoomSpeed') ?></th><td><input type="checkbox" name="newControl[HasZoomSpeed]" value="1"<?php if ( !empty($newControl['HasZoomSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinZoomSpeed') ?></th><td><input type="text" name="newControl[MinZoomSpeed]" value="<?php echo validHtmlStr($newControl['MinZoomSpeed']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxZoomSpeed') ?></th><td><input type="text" name="newControl[MaxZoomSpeed]" value="<?php echo validHtmlStr($newControl['MaxZoomSpeed']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinZoomSpeed') ?></th><td><input type="number" name="newControl[MinZoomSpeed]" value="<?php echo validHtmlStr($newControl['MinZoomSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxZoomSpeed') ?></th><td><input type="number" name="newControl[MaxZoomSpeed]" value="<?php echo validHtmlStr($newControl['MaxZoomSpeed']) ?>"/></td></tr>
<?php
break;
}
@ -426,13 +401,13 @@ switch ( $tab )
<tr><th scope="row"><?php echo translate('CanFocusAbs') ?></th><td><input type="checkbox" name="newControl[CanFocusAbs]" value="1"<?php if ( !empty($newControl['CanFocusAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanFocusRel') ?></th><td><input type="checkbox" name="newControl[CanFocusRel]" value="1"<?php if ( !empty($newControl['CanFocusRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanFocusCon') ?></th><td><input type="checkbox" name="newControl[CanFocusCon]" value="1"<?php if ( !empty($newControl['CanFocusCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinFocusRange') ?></th><td><input type="text" name="newControl[MinFocusRange]" value="<?php echo validHtmlStr($newControl['MinFocusRange']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxFocusRange') ?></th><td><input type="text" name="newControl[MaxFocusRange]" value="<?php echo validHtmlStr($newControl['MaxFocusRange']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinFocusStep') ?></th><td><input type="text" name="newControl[MinFocusStep]" value="<?php echo validHtmlStr($newControl['MinFocusStep']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxFocusStep') ?></th><td><input type="text" name="newControl[MaxFocusStep]" value="<?php echo validHtmlStr($newControl['MaxFocusStep']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinFocusRange') ?></th><td><input type="number" name="newControl[MinFocusRange]" value="<?php echo validHtmlStr($newControl['MinFocusRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxFocusRange') ?></th><td><input type="number" name="newControl[MaxFocusRange]" value="<?php echo validHtmlStr($newControl['MaxFocusRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinFocusStep') ?></th><td><input type="number" name="newControl[MinFocusStep]" value="<?php echo validHtmlStr($newControl['MinFocusStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxFocusStep') ?></th><td><input type="number" name="newControl[MaxFocusStep]" value="<?php echo validHtmlStr($newControl['MaxFocusStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasFocusSpeed') ?></th><td><input type="checkbox" name="newControl[HasFocusSpeed]" value="1"<?php if ( !empty($newControl['HasFocusSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinFocusSpeed') ?></th><td><input type="text" name="newControl[MinFocusSpeed]" value="<?php echo validHtmlStr($newControl['MinFocusSpeed']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxFocusSpeed') ?></th><td><input type="text" name="newControl[MaxFocusSpeed]" value="<?php echo validHtmlStr($newControl['MaxFocusSpeed']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinFocusSpeed') ?></th><td><input type="number" name="newControl[MinFocusSpeed]" value="<?php echo validHtmlStr($newControl['MinFocusSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxFocusSpeed') ?></th><td><input type="number" name="newControl[MaxFocusSpeed]" value="<?php echo validHtmlStr($newControl['MaxFocusSpeed']) ?>"/></td></tr>
<?php
break;
}
@ -444,13 +419,13 @@ switch ( $tab )
<tr><th scope="row"><?php echo translate('CanIrisAbs') ?></th><td><input type="checkbox" name="newControl[CanIrisAbs]" value="1"<?php if ( !empty($newControl['CanIrisAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanIrisRel') ?></th><td><input type="checkbox" name="newControl[CanIrisRel]" value="1"<?php if ( !empty($newControl['CanIrisRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanIrisCon') ?></th><td><input type="checkbox" name="newControl[CanIrisCon]" value="1"<?php if ( !empty($newControl['CanIrisCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinIrisRange') ?></th><td><input type="text" name="newControl[MinIrisRange]" value="<?php echo validHtmlStr($newControl['MinIrisRange']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxIrisRange') ?></th><td><input type="text" name="newControl[MaxIrisRange]" value="<?php echo validHtmlStr($newControl['MaxIrisRange']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinIrisStep') ?></th><td><input type="text" name="newControl[MinIrisStep]" value="<?php echo validHtmlStr($newControl['MinIrisStep']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxIrisStep') ?></th><td><input type="text" name="newControl[MaxIrisStep]" value="<?php echo validHtmlStr($newControl['MaxIrisStep']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinIrisRange') ?></th><td><input type="number" name="newControl[MinIrisRange]" value="<?php echo validHtmlStr($newControl['MinIrisRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxIrisRange') ?></th><td><input type="number" name="newControl[MaxIrisRange]" value="<?php echo validHtmlStr($newControl['MaxIrisRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinIrisStep') ?></th><td><input type="number" name="newControl[MinIrisStep]" value="<?php echo validHtmlStr($newControl['MinIrisStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxIrisStep') ?></th><td><input type="number" name="newControl[MaxIrisStep]" value="<?php echo validHtmlStr($newControl['MaxIrisStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasIrisSpeed') ?></th><td><input type="checkbox" name="newControl[HasIrisSpeed]" value="1"<?php if ( !empty($newControl['HasIrisSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinIrisSpeed') ?></th><td><input type="text" name="newControl[MinIrisSpeed]" value="<?php echo validHtmlStr($newControl['MinIrisSpeed']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxIrisSpeed') ?></th><td><input type="text" name="newControl[MaxIrisSpeed]" value="<?php echo validHtmlStr($newControl['MaxIrisSpeed']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinIrisSpeed') ?></th><td><input type="number" name="newControl[MinIrisSpeed]" value="<?php echo validHtmlStr($newControl['MinIrisSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxIrisSpeed') ?></th><td><input type="number" name="newControl[MaxIrisSpeed]" value="<?php echo validHtmlStr($newControl['MaxIrisSpeed']) ?>"/></td></tr>
<?php
break;
}
@ -462,13 +437,13 @@ switch ( $tab )
<tr><th scope="row"><?php echo translate('CanGainAbs') ?></th><td><input type="checkbox" name="newControl[CanGainAbs]" value="1"<?php if ( !empty($newControl['CanGainAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanGainRel') ?></th><td><input type="checkbox" name="newControl[CanGainRel]" value="1"<?php if ( !empty($newControl['CanGainRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanGainCon') ?></th><td><input type="checkbox" name="newControl[CanGainCon]" value="1"<?php if ( !empty($newControl['CanGainCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinGainRange') ?></th><td><input type="text" name="newControl[MinGainRange]" value="<?php echo validHtmlStr($newControl['MinGainRange']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxGainRange') ?></th><td><input type="text" name="newControl[MaxGainRange]" value="<?php echo validHtmlStr($newControl['MaxGainRange']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinGainStep') ?></th><td><input type="text" name="newControl[MinGainStep]" value="<?php echo validHtmlStr($newControl['MinGainStep']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxGainStep') ?></th><td><input type="text" name="newControl[MaxGainStep]" value="<?php echo validHtmlStr($newControl['MaxGainStep']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinGainRange') ?></th><td><input type="number" name="newControl[MinGainRange]" value="<?php echo validHtmlStr($newControl['MinGainRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxGainRange') ?></th><td><input type="number" name="newControl[MaxGainRange]" value="<?php echo validHtmlStr($newControl['MaxGainRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinGainStep') ?></th><td><input type="number" name="newControl[MinGainStep]" value="<?php echo validHtmlStr($newControl['MinGainStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxGainStep') ?></th><td><input type="number" name="newControl[MaxGainStep]" value="<?php echo validHtmlStr($newControl['MaxGainStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasGainSpeed') ?></th><td><input type="checkbox" name="newControl[HasGainSpeed]" value="1"<?php if ( !empty($newControl['HasGainSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinGainSpeed') ?></th><td><input type="text" name="newControl[MinGainSpeed]" value="<?php echo validHtmlStr($newControl['MinGainSpeed']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxGainSpeed') ?></th><td><input type="text" name="newControl[MaxGainSpeed]" value="<?php echo validHtmlStr($newControl['MaxGainSpeed']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinGainSpeed') ?></th><td><input type="number" name="newControl[MinGainSpeed]" value="<?php echo validHtmlStr($newControl['MinGainSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxGainSpeed') ?></th><td><input type="number" name="newControl[MaxGainSpeed]" value="<?php echo validHtmlStr($newControl['MaxGainSpeed']) ?>"/></td></tr>
<?php
break;
}
@ -480,13 +455,13 @@ switch ( $tab )
<tr><th scope="row"><?php echo translate('CanWhiteAbs') ?></th><td><input type="checkbox" name="newControl[CanWhiteAbs]" value="1"<?php if ( !empty($newControl['CanWhiteAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanWhiteRel') ?></th><td><input type="checkbox" name="newControl[CanWhiteRel]" value="1"<?php if ( !empty($newControl['CanWhiteRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanWhiteCon') ?></th><td><input type="checkbox" name="newControl[CanWhiteCon]" value="1"<?php if ( !empty($newControl['CanWhiteCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinWhiteRange') ?></th><td><input type="text" name="newControl[MinWhiteRange]" value="<?php echo validHtmlStr($newControl['MinWhiteRange']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxWhiteRange') ?></th><td><input type="text" name="newControl[MaxWhiteRange]" value="<?php echo validHtmlStr($newControl['MaxWhiteRange']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinWhiteStep') ?></th><td><input type="text" name="newControl[MinWhiteStep]" value="<?php echo validHtmlStr($newControl['MinWhiteStep']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxWhiteStep') ?></th><td><input type="text" name="newControl[MaxWhiteStep]" value="<?php echo validHtmlStr($newControl['MaxWhiteStep']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinWhiteRange') ?></th><td><input type="number" name="newControl[MinWhiteRange]" value="<?php echo validHtmlStr($newControl['MinWhiteRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxWhiteRange') ?></th><td><input type="number" name="newControl[MaxWhiteRange]" value="<?php echo validHtmlStr($newControl['MaxWhiteRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinWhiteStep') ?></th><td><input type="number" name="newControl[MinWhiteStep]" value="<?php echo validHtmlStr($newControl['MinWhiteStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxWhiteStep') ?></th><td><input type="number" name="newControl[MaxWhiteStep]" value="<?php echo validHtmlStr($newControl['MaxWhiteStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasWhiteSpeed') ?></th><td><input type="checkbox" name="newControl[HasWhiteSpeed]" value="1"<?php if ( !empty($newControl['HasWhiteSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinWhiteSpeed') ?></th><td><input type="text" name="newControl[MinWhiteSpeed]" value="<?php echo validHtmlStr($newControl['MinWhiteSpeed']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxWhiteSpeed') ?></th><td><input type="text" name="newControl[MaxWhiteSpeed]" value="<?php echo validHtmlStr($newControl['MaxWhiteSpeed']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('MinWhiteSpeed') ?></th><td><input type="number" name="newControl[MinWhiteSpeed]" value="<?php echo validHtmlStr($newControl['MinWhiteSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxWhiteSpeed') ?></th><td><input type="number" name="newControl[MaxWhiteSpeed]" value="<?php echo validHtmlStr($newControl['MaxWhiteSpeed']) ?>"/></td></tr>
<?php
break;
}
@ -494,7 +469,7 @@ switch ( $tab )
{
?>
<tr><th scope="row"><?php echo translate('HasPresets') ?></th><td><input type="checkbox" name="newControl[HasPresets]" value="1"<?php if ( !empty($newControl['HasPresets']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('NumPresets') ?></th><td><input type="text" name="newControl[NumPresets]" value="<?php echo validHtmlStr($newControl['NumPresets']) ?>" size="8"/></td></tr>
<tr><th scope="row"><?php echo translate('NumPresets') ?></th><td><input type="number" name="newControl[NumPresets]" value="<?php echo validHtmlStr($newControl['NumPresets']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasHomePreset') ?></th><td><input type="checkbox" name="newControl[HasHomePreset]" value="1"<?php if ( !empty($newControl['HasHomePreset']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanSetPresets') ?></th><td><input type="checkbox" name="newControl[CanSetPresets]" value="1"<?php if ( !empty($newControl['CanSetPresets']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<?php
@ -505,7 +480,8 @@ switch ( $tab )
</tbody>
</table>
<div id="contentButtons">
<input type="submit" value="<?php echo translate('Save') ?>"<?php if ( !canEdit( 'Control' ) ) { ?> disabled="disabled"<?php } ?>/><input type="button" value="<?php echo translate('Cancel') ?>" data-on-click="closeWindow"/>
<button type="submit" value="Save"<?php if ( !canEdit( 'Control' ) ) { ?> disabled="disabled"<?php } ?>><?php echo translate('Save') ?></button>
<button type="button" data-on-click="closeWindow"><?php echo translate('Cancel') ?></button>
</div>
</form>
</div>

View File

@ -138,7 +138,7 @@ $disk_space_total = 0;
$event_count = 0;
while ( $event_row = dbFetchNext($results) ) {
$event = new ZM\Event($event_row);
$scale = max(reScale(SCALE_BASE, $event->DefaultScale(), ZM_WEB_DEFAULT_SCALE), SCALE_BASE);
$scale = max(reScale(SCALE_BASE, $event->Monitor()->DefaultScale(), ZM_WEB_DEFAULT_SCALE), SCALE_BASE);
?>
<tr<?php echo $event->Archived() ? ' class="archived"' : '' ?>>
<td class="colId">

View File

@ -229,7 +229,7 @@ for ( $i=0; $i < count($terms); $i++ ) {
}
?>
<td><?php if ( count($terms) > 2 ) { echo htmlSelect("filter[Query][terms][$i][obr]", $obracketTypes, $term['obr']); } else { ?>&nbsp;<?php } ?></td>
<td><?php echo htmlSelect("filter[Query][terms][$i][attr]", $attrTypes, $term['attr'], 'checkValue(this);'); ?></td>
<td><?php echo htmlSelect("filter[Query][terms][$i][attr]", $attrTypes, $term['attr'], array('data-on-change-this'=>'checkValue')); ?></td>
<?php
if ( isset($term['attr']) ) {
if ( $term['attr'] == 'Archived' ) {

View File

@ -3,21 +3,131 @@ function validateForm( form ) {
// If "Can Move" is enabled, then the end user must also select at least one of the other check boxes (excluding Can Move Diagonally)
if ( form.elements['newControl[CanMove]'].checked ) {
if ( !(form.elements['newControl[CanMoveCon]'].checked || form.elements['newControl[CanMoveRel]'].checked || form.elements['newControl[CanMoveAbs]'].checked || form.elements['newControl[CanMoveMap]'].checked) ) {
errors[errors.length] = "In addition to \"Can Move\", you also must select at least one of: \"Can Move Mapped\", \"Can Move Absolute\", \"Can Move Relative\", or \"Can Move Continuous\"";
if ( !(
form.elements['newControl[CanMoveCon]'].checked
||
form.elements['newControl[CanMoveRel]'].checked
||
form.elements['newControl[CanMoveAbs]'].checked
||
form.elements['newControl[CanMoveMap]'].checked
) ) {
errors[errors.length] = 'In addition to "Can Move", you also must select at least one of: "Can Move Mapped", "Can Move Absolute", "Can Move Relative", or "Can Move Continuous"';
}
} else {
// Now lets check for the opposite condition. If any of the boxes below Can Move are checked, but Can Move is not checked then signal an error
if ( form.elements['newControl[CanMoveCon]'].checked || form.elements['newControl[CanMoveRel]'].checked || form.elements['newControl[CanMoveAbs]'].checked || form.elements['newControl[CanMoveMap]'].checked || form.elements['newControl[CanMoveDiag]'].checked ) {
errors[errors.length] = "\"Can Move\" must also be selected if any one of the movement types are sleceted";
if ( form.elements['newControl[CanMoveCon]'].checked
||
form.elements['newControl[CanMoveRel]'].checked
||
form.elements['newControl[CanMoveAbs]'].checked
||
form.elements['newControl[CanMoveMap]'].checked
||
form.elements['newControl[CanMoveDiag]'].checked
) {
errors[errors.length] = '"Can Move" must also be selected if any one of the movement types are selected.';
}
}
// If "Can Zoom" is enabled, then the end user must also select at least one of the other check boxes
if ( form.elements['newControl[CanZoom]'].checked ) {
if ( !(
form.elements['newControl[CanZoomCon]'].checked
||
form.elements['newControl[CanZoomRel]'].checked
||
form.elements['newControl[CanZoomAbs]'].checked
) ) {
errors[errors.length] = 'In addition to "Can Zoom", you also must select at least one of: "Can Zoom Absolute", "Can Zoom Relative", or "Can Zoom Continuous"';
}
} else {
// Now lets check for the opposite condition. If any of the boxes below Can Zoom are checked, but Can Zoom is not checked then signal an error
if ( form.elements['newControl[CanZoomCon]'].checked
||
form.elements['newControl[CanZoomRel]'].checked
||
form.elements['newControl[CanZoomAbs]'].checked
) {
errors[errors.length] = '"Can Move" must also be selected if any one of the zoom types are selected.';
}
}
// If "Can Zoom" is enabled, then the end user must also select at least one of the other check boxes
if ( form.elements['newControl[CanFocus]'].checked ) {
if ( !(
form.elements['newControl[CanFocusCon]'].checked
||
form.elements['newControl[CanFocusRel]'].checked
||
form.elements['newControl[CanFocusAbs]'].checked
) ) {
errors[errors.length] = 'In addition to "Can Focus", you also must select at least one of: "Can Focus Absolute", "Can Focus Relative", or "Can Focus Continuous"';
}
} else {
// Now lets check for the opposite condition. If any of the boxes below Can Zoom are checked, but Can Zoom is not checked then signal an error
if ( form.elements['newControl[CanFocusCon]'].checked
||
form.elements['newControl[CanFocusRel]'].checked
||
form.elements['newControl[CanFocusAbs]'].checked
) {
errors[errors.length] = '"Can Focus" must also be selected if any one of the focus types are selected.';
}
}
// If "Can White" is enabled, then the end user must also select at least one of the other check boxes
if ( form.elements['newControl[CanWhite]'].checked ) {
if ( !(
form.elements['newControl[CanWhiteCon]'].checked
||
form.elements['newControl[CanWhiteRel]'].checked
||
form.elements['newControl[CanWhiteAbs]'].checked
) ) {
errors[errors.length] = 'In addition to "Can White Balance", you also must select at least one of: "Can White Bal Absolute", "Can White Bal Relative", or "Can White Bal Continuous"';
}
} else {
// Now lets check for the opposite condition. If any of the boxes below Can Zoom are checked, but Can Zoom is not checked then signal an error
if ( form.elements['newControl[CanWhiteCon]'].checked
||
form.elements['newControl[CanWhiteRel]'].checked
||
form.elements['newControl[CanWhiteAbs]'].checked
) {
errors[errors.length] = '"Can White Balance" must also be selected if any one of the white balance types are selected.';
}
}
// If "Can Iris" is enabled, then the end user must also select at least one of the other check boxes
if ( form.elements['newControl[CanIris]'].checked ) {
if ( !(
form.elements['newControl[CanIrisCon]'].checked
||
form.elements['newControl[CanIrisRel]'].checked
||
form.elements['newControl[CanIrisAbs]'].checked
) ) {
errors[errors.length] = 'In addition to "Can Iris", you also must select at least one of: "Can Iris Absolute", "Can Iris Relative", or "Can Iris Continuous"';
}
} else {
// Now lets check for the opposite condition. If any of the boxes below Can Zoom are checked, but Can Zoom is not checked then signal an error
if ( form.elements['newControl[CanIrisCon]'].checked
||
form.elements['newControl[CanIrisRel]'].checked
||
form.elements['newControl[CanIrisAbs]'].checked
) {
errors[errors.length] = '"Can Iris" must also be selected if any one of the iris types are selected.';
}
}
if ( errors.length ) {
alert( errors.join( "\n" ) );
return ( false );
alert(errors.join("\n"));
return false;
}
return ( true );
return true;
}

View File

@ -57,7 +57,7 @@ function setAlarmCues(data) {
function renderAlarmCues(containerEl) {
if ( !( cueFrames && cueFrames.length ) ) {
console.log("No cue frames for event");
console.log('No cue frames for event');
return;
}
// This uses the Delta of the last frame to get the length of the event. I can't help but wonder though
@ -139,7 +139,7 @@ function setButtonState( element, butClass ) {
element.disabled = false;
}
} else {
console.log("Element was null in setButtonState");
console.log('Element was null in setButtonState');
}
}
@ -211,7 +211,7 @@ var lastEventId = 0;
var zmsBroke = false; //Use alternate navigation if zms has crashed
function getCmdResponse( respObj, respText ) {
if ( checkStreamForErrors("getCmdResponse", respObj) ) {
if ( checkStreamForErrors('getCmdResponse', respObj) ) {
console.log('Got an error from getCmdResponse');
console.log(respObj);
console.log(respText);
@ -541,9 +541,9 @@ var scroll = null;
var currEventId = null;
var CurEventDefVideoPath = null;
function getEventResponse( respObj, respText ) {
if ( checkStreamForErrors( "getEventResponse", respObj ) ) {
console.log("getEventResponse: errors" );
function getEventResponse(respObj, respText) {
if ( checkStreamForErrors('getEventResponse', respObj) ) {
console.log('getEventResponse: errors');
return;
}
@ -582,7 +582,7 @@ function getEventResponse( respObj, respText ) {
//eventImg.setStyles( { 'width': eventData.width, 'height': eventData.height } );
if ( vid && CurEventDefVideoPath ) {
vid.src({type: 'video/mp4', src: CurEventDefVideoPath}); //Currently mp4 is all we use
console.log("getEventResponse");
console.log('getEventResponse');
initialAlarmCues(eventData.Id);//ajax and render, new event
addVideoTimingTrack(vid, LabelFormat, eventData.MonitorName, eventData.Length, eventData.StartTime);
CurEventDefVideoPath = null;
@ -644,7 +644,7 @@ var frameBatch = 40;
function loadEventThumb( event, frame, loadImage ) {
var thumbImg = $('eventThumb'+frame.FrameId);
if ( !thumbImg ) {
console.error( "No holder found for frame "+frame.FrameId );
console.error('No holder found for frame '+frame.FrameId);
return;
}
var img = new Asset.image( imagePrefix+frame.EventId+"&fid="+frame.FrameId,
@ -666,31 +666,31 @@ function loadEventThumb( event, frame, loadImage ) {
);
}
function loadEventImage( event, frame ) {
console.debug( "Loading "+event.Id+"/"+frame.FrameId );
function loadEventImage(event, frame) {
console.debug('Loading '+event.Id+'/'+frame.FrameId);
var eventImg = $('eventImage');
var thumbImg = $('eventThumb'+frame.FrameId);
if ( eventImg.getProperty( 'src' ) != thumbImg.getProperty( 'src' ) ) {
if ( eventImg.getProperty('src') != thumbImg.getProperty('src') ) {
var eventImagePanel = $('eventImagePanel');
if ( eventImagePanel.getStyle( 'display' ) != 'none' ) {
var lastThumbImg = $('eventThumb'+eventImg.getProperty( 'alt' ));
if ( eventImagePanel.getStyle('display') != 'none' ) {
var lastThumbImg = $('eventThumb'+eventImg.getProperty('alt'));
lastThumbImg.removeClass('selected');
lastThumbImg.setOpacity( 1.0 );
lastThumbImg.setOpacity(1.0);
}
$('eventImageBar').setStyle( 'width', event.Width );
if ( frame.Type=='Alarm' ) {
$('eventImageStats').removeClass( 'hidden' );
$('eventImageBar').setStyle('width', event.Width);
if ( frame.Type == 'Alarm' ) {
$('eventImageStats').removeClass('hidden');
} else {
$('eventImageStats').addClass( 'hidden' );
$('eventImageStats').addClass('hidden');
}
thumbImg.addClass( 'selected' );
thumbImg.setOpacity( 0.5 );
thumbImg.addClass('selected');
thumbImg.setOpacity(0.5);
if ( eventImagePanel.getStyle( 'display' ) == 'none' ) {
eventImagePanel.setOpacity( 0 );
eventImagePanel.setStyle( 'display', 'inline-block' );
if ( eventImagePanel.getStyle('display') == 'none' ) {
eventImagePanel.setOpacity(0);
eventImagePanel.setStyle('display', 'inline-block');
new Fx.Tween( eventImagePanel, {duration: 500, transition: Fx.Transitions.Sine} ).start( 'opacity', 0, 1 );
}
@ -702,29 +702,29 @@ function loadEventImage( event, frame ) {
'height': $j('#eventThumbs').height() - $j('#eventImageBar').outerHeight(true)-10
} );
$('eventImageNo').set( 'text', frame.FrameId );
$('eventImageNo').set('text', frame.FrameId);
$('prevImageBtn').disabled = (frame.FrameId==1);
$('nextImageBtn').disabled = (frame.FrameId==event.Frames);
}
}
function hideEventImageComplete() {
var thumbImg = $('eventThumb'+$('eventImage').getProperty( 'alt' ));
var thumbImg = $('eventThumb'+$('eventImage').getProperty('alt'));
if ( thumbImg ) {
thumbImg.removeClass('selected');
thumbImg.setOpacity( 1.0 );
thumbImg.setOpacity(1.0);
} else {
console.log("Unable to find eventThumb at " + 'eventThumb'+$('eventImage').getProperty( 'alt' ) );
console.log('Unable to find eventThumb at eventThumb'+$('eventImage').getProperty('alt'));
}
$('prevImageBtn').disabled = true;
$('nextImageBtn').disabled = true;
$('eventImagePanel').setStyle( 'display', 'none' );
$('eventImageStats').addClass( 'hidden' );
$('eventImagePanel').setStyle('display', 'none');
$('eventImageStats').addClass('hidden');
}
function hideEventImage() {
if ( $('eventImagePanel').getStyle( 'display' ) != 'none' ) {
new Fx.Tween( $('eventImagePanel'), {duration: 500, transition: Fx.Transitions.Sine, onComplete: hideEventImageComplete} ).start( 'opacity', 1, 0 );
if ( $('eventImagePanel').getStyle('display') != 'none' ) {
new Fx.Tween( $('eventImagePanel'), {duration: 500, transition: Fx.Transitions.Sine, onComplete: hideEventImageComplete} ).start('opacity', 1, 0);
}
}
@ -751,15 +751,15 @@ function resetEventStills() {
}
}
function getFrameResponse( respObj, respText ) {
if ( checkStreamForErrors( "getFrameResponse", respObj ) ) {
function getFrameResponse(respObj, respText) {
if ( checkStreamForErrors('getFrameResponse', respObj) ) {
return;
}
var frame = respObj.frameimage;
if ( !eventData ) {
console.error( "No event "+frame.EventId+" found" );
console.error('No event '+frame.EventId+' found');
return;
}
@ -769,21 +769,21 @@ function getFrameResponse( respObj, respText ) {
eventData['frames'][frame.FrameId] = frame;
loadEventThumb( eventData, frame, respObj.loopback=="true" );
loadEventThumb(eventData, frame, respObj.loopback=="true");
}
var frameReq = new Request.JSON( {url: thisUrl, method: 'get', timeout: AJAX_TIMEOUT, link: 'chain', onSuccess: getFrameResponse} );
function frameQuery( eventId, frameId, loadImage ) {
var parms = "view=request&request=status&entity=frameimage&id[0]="+eventId+"&id[1]="+frameId+"&loopback="+loadImage;
frameReq.send( parms );
frameReq.send(parms);
}
var currFrameId = null;
function checkFrames( eventId, frameId, loadImage ) {
if ( !eventData ) {
console.error( "No event "+eventId+" found" );
console.error("No event "+eventId+" found");
return;
}
@ -804,29 +804,30 @@ function checkFrames( eventId, frameId, loadImage ) {
for ( var fid = loFid; fid <= hiFid; fid++ ) {
if ( !$('eventThumb'+fid) ) {
var img = new Element( 'img', {'id': 'eventThumb'+fid, 'src': 'graphics/transparent.png', 'alt': fid, 'class': 'placeholder'} );
img.addEvent( 'click', function() {
eventData['frames'][fid] = null; checkFrames( eventId, fid );
} );
frameQuery( eventId, fid, loadImage && (fid == frameId) );
var imgs = $('eventThumbs').getElements( 'img' );
var img = new Element('img', {'id': 'eventThumb'+fid, 'src': 'graphics/transparent.png', 'alt': fid, 'class': 'placeholder'});
img.addEvent('click', function() {
eventData['frames'][fid] = null;
checkFrames(eventId, fid);
});
frameQuery(eventId, fid, loadImage && (fid == frameId));
var imgs = $('eventThumbs').getElements('img');
var injected = false;
if ( fid < imgs.length ) {
img.inject( imgs[fid-1], 'before' );
img.inject(imgs[fid-1], 'before');
injected = true;
} else {
injected = imgs.some(
function( thumbImg, index ) {
if ( parseInt(img.getProperty( 'alt' )) < parseInt(thumbImg.getProperty( 'alt' )) ) {
img.inject( thumbImg, 'before' );
return ( true );
if ( parseInt(img.getProperty('alt')) < parseInt(thumbImg.getProperty('alt')) ) {
img.inject(thumbImg, 'before');
return true;
}
return ( false );
return false;
}
);
}
if ( !injected ) {
img.inject( $('eventThumbs') );
img.inject($('eventThumbs'));
}
var scale = parseInt(img.getStyle('height'));
img.setStyles( {
@ -923,7 +924,7 @@ function deleteEvent() {
getActResponse(respObj, respText);
// We must wait for the deletion to happen before navigating to the next
// event or this request will be cancelled.
streamNext( true );
streamNext(true);
},
});
deleteReq.send("view=request&request=event&id="+eventData.Id+"&action=delete");
@ -931,43 +932,43 @@ function deleteEvent() {
function renameEvent() {
var newName = $('eventName').get('value');
actQuery( 'rename', {eventName: newName} );
actQuery('rename', {eventName: newName});
}
function editEvent() {
createPopup( '?view=eventdetail&eid='+eventData.Id, 'zmEventDetail', 'eventdetail' );
createPopup('?view=eventdetail&eid='+eventData.Id, 'zmEventDetail', 'eventdetail');
}
function exportEvent() {
createPopup( '?view=export&eid='+eventData.Id, 'zmExport', 'export' );
createPopup('?view=export&eid='+eventData.Id, 'zmExport', 'export');
}
function archiveEvent() {
actQuery( 'archive' );
actQuery('archive');
}
function unarchiveEvent() {
actQuery( 'unarchive' );
actQuery('unarchive');
}
function showEventFrames() {
createPopup( '?view=frames&eid='+eventData.Id, 'zmFrames', 'frames', WEB_LIST_THUMB_WIDTH, WEB_LIST_THUMB_HEIGHT );
createPopup('?view=frames&eid='+eventData.Id, 'zmFrames', 'frames', WEB_LIST_THUMB_WIDTH, WEB_LIST_THUMB_HEIGHT);
}
function showStream() {
$('eventStills').addClass( 'hidden' );
$('eventVideo').removeClass( 'hidden' );
$('eventStills').addClass('hidden');
$('eventVideo').removeClass('hidden');
$('stillsEvent').removeClass( 'hidden' );
$('streamEvent').addClass( 'hidden' );
$('stillsEvent').removeClass('hidden');
$('streamEvent').addClass('hidden');
streamMode = 'video';
if (scale == 'auto') changeScale();
}
function showStills() {
$('eventStills').removeClass( 'hidden' );
$('eventVideo').addClass( 'hidden' );
$('eventStills').removeClass('hidden');
$('eventVideo').addClass('hidden');
if (vid && ( vid.paused != true ) ) {
// Pause the video
@ -978,14 +979,14 @@ function showStills() {
//playButton.innerHTML = "Play";
}
$('stillsEvent').addClass( 'hidden' );
$('streamEvent').removeClass( 'hidden' );
$('stillsEvent').addClass('hidden');
$('streamEvent').removeClass('hidden');
streamMode = 'stills';
pauseClicked();
if ( !scroll ) {
scroll = new Fx.Scroll( 'eventThumbs', {
scroll = new Fx.Scroll('eventThumbs', {
wait: false,
duration: 500,
offset: {'x': 0, 'y': 0},
@ -999,17 +1000,17 @@ function showStills() {
function showFrameStats() {
var fid = $('eventImageNo').get('text');
createPopup( '?view=stats&eid='+eventData.Id+'&fid='+fid, 'zmStats', 'stats', eventData.Width, eventData.Height );
createPopup('?view=stats&eid='+eventData.Id+'&fid='+fid, 'zmStats', 'stats', eventData.Width, eventData.Height);
}
function videoEvent() {
createPopup( '?view=video&eid='+eventData.Id, 'zmVideo', 'video', eventData.Width, eventData.Height );
createPopup('?view=video&eid='+eventData.Id, 'zmVideo', 'video', eventData.Width, eventData.Height);
}
// Called on each event load because each event can be a different width
function drawProgressBar() {
var barWidth = $j('#evtStream').width();
$j('#progressBar').css( 'width', barWidth );
$j('#progressBar').css('width', barWidth);
}
// Shows current stream progress.
@ -1032,8 +1033,8 @@ function progressBarNav() {
function handleClick( event ) {
var target = event.target;
if (vid) {
if (target.id != 'videoobj') return; //ignore clicks on control bar
if ( vid ) {
if (target.id != 'videoobj') return; // ignore clicks on control bar
var x = event.offsetX;
var y = event.offsetY;
} else {
@ -1041,9 +1042,9 @@ function handleClick( event ) {
var y = event.page.y - $(target).getTop();
}
if (event.shift || event.shiftKey) {//handle both jquery and mootools
if ( event.shift || event.shiftKey ) { // handle both jquery and mootools
streamPan(x, y);
} else if (vid && event.ctrlKey) { //allow zoom out by control click. useful in fullscreen
} else if ( vid && event.ctrlKey ) { // allow zoom out by control click. useful in fullscreen
vjsPanZoom('zoomOut', x, y);
} else {
streamZoomIn(x, y);
@ -1072,7 +1073,7 @@ function initPage() {
}
} else {
progressBarNav();
streamCmdTimer = streamQuery.delay( 250 );
streamCmdTimer = streamQuery.delay(250);
if ( canStreamNative ) {
var imageFeed = $('imageFeed');
if ( !imageFeed ) {
@ -1082,16 +1083,16 @@ function initPage() {
if ( !streamImg ) {
streamImg = imageFeed.getElement('object');
}
$(streamImg).addEvent( 'click', function( event ) {
handleClick( event );
} );
$(streamImg).addEvent('click', function(event) {
handleClick(event);
});
}
}
}
nearEventsQuery(eventData.Id);
initialAlarmCues(eventData.Id); //call ajax+renderAlarmCues
if (scale == "auto") changeScale();
if ( scale == 'auto' ) changeScale();
}
// Kick everything off
window.addEventListener( 'DOMContentLoaded', initPage );
window.addEventListener('DOMContentLoaded', initPage);

View File

@ -4,7 +4,7 @@ function configureExportButton(element) {
var form = element.form;
var eventCount = 0;
document.querySelectorAll('input[name="eids[]"]').forEach(function(el){
document.querySelectorAll('input[name="eids[]"]').forEach(function(el) {
if ( el.checked ) {
eventCount ++;
}
@ -43,7 +43,6 @@ function exportProgress() {
}
function exportResponse(respObj, respText) {
clearInterval(exportTimer);
if ( respObj.result != 'Ok' ) {
$('exportProgressTicker').set('text', respObj.message);

View File

@ -149,8 +149,8 @@ function parseRows(rows) {
var queryPrefix = 'filter[Query][terms][';
var inputTds = rows.eq(rowNum).children();
if (rowNum == 0) inputTds.eq(0).html('&nbsp'); //Remove and from first term
if (rowNum > 0) { //add and/or to 1+
if ( rowNum == 0 ) inputTds.eq(0).html('&nbsp'); //Remove and from first term
if ( rowNum > 0 ) { //add and/or to 1+
var cnjVal = inputTds.eq(0).children().val();
var conjSelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][cnj]').attr('id', queryPrefix + rowNum + '][cnj]');
$j.each(conjTypes, function(i) {
@ -174,14 +174,14 @@ function parseRows(rows) {
inputTds.eq(1).html(obrSelect).children().val(obrVal); //Set bracket contents and assign saved value
inputTds.eq(5).html(cbrSelect).children().val(cbrVal);
} else {
inputTds.eq(1).html('&nbsp'); //Blank if there aren't enough terms for brackets
inputTds.eq(1).html('&nbsp'); // Blank if there aren't enough terms for brackets
inputTds.eq(5).html('&nbsp');
}
if ( rows.length == 1 ) {
inputTds.eq(6).find(':input[value="-"]').prop('disabled', true); //enable/disable remove row button
inputTds.eq(6).find('button[data-on-click-this="delTerm"]').prop('disabled', true); //enable/disable remove row button
} else {
inputTds.eq(6).find(':input[value="-"]').prop('disabled', false);
inputTds.eq(6).find('button[data-on-click-this="delTerm"]').prop('disabled', false);
}
var attr = inputTds.eq(2).children().val();
@ -276,7 +276,7 @@ if ( 0 ) {
term[2] = rowNum;
inputTds.eq(2).children().eq(0).attr('name', 'filter'+stringFilter(term));
inputTds.eq(2).children().eq(0).attr('id', 'filter'+stringFilter(term));
} // end foreach term/row
} //End for each term/row
history.replaceState(null, null, '?view=filter&' + $j('#contentForm').serialize());
}

View File

@ -172,9 +172,9 @@ function clearLog() {
logReq.cancel();
var clearParms = 'view=request&request=log&task=delete';
var clearReq = new Request.JSON( {url: thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: clearResponse} );
var tbody = $(logTable).getElement( 'tbody' );
var rows = tbody.getElements( 'tr' );
var clearReq = new Request.JSON({url: thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: clearResponse});
var tbody = $(logTable).getElement('tbody');
var rows = tbody.getElements('tr');
if ( rows ) {
var minTime = rows[0].getElement('td').get('text');
clearParms += "&minTime="+encodeURIComponent(minTime);
@ -190,7 +190,7 @@ function filterLog() {
filterFields.each(
function( field ) {
var selector = $('filter['+field+']');
if ( ! selector ) {
if ( !selector ) {
if ( window.console && window.console.log ) {
window.console.log('No selector found for ' + field);
}
@ -226,9 +226,9 @@ function exportResponse( response ) {
function exportFail( request ) {
$('exportLog').unspin();
$('exportErrorText').set('text', request.status+' / '+request.statusText );
$('exportErrorText').set('text', request.status+' / '+request.statusText);
$('exportError').show();
Error('Export request failed: '+request.status+' / '+request.statusText );
Error('Export request failed: '+request.status+' / '+request.statusText);
}
function exportRequest() {
@ -237,7 +237,7 @@ function exportRequest() {
$('exportError').hide();
if ( form.validate() ) {
var exportParms = "view=request&request=log&task=export";
var exportReq = new Request.JSON( {url: thisUrl, method: 'post', link: 'cancel', onSuccess: exportResponse, onFailure: exportFail} );
var exportReq = new Request.JSON({url: thisUrl, method: 'post', link: 'cancel', onSuccess: exportResponse, onFailure: exportFail});
var selection = form.getElement('input[name=selector]:checked').get('value');
if ( selection == 'filter' || selection == 'current' ) {
$$('#filters select').each(
@ -256,7 +256,7 @@ function exportRequest() {
exportParms += "&maxTime="+encodeURIComponent(maxTime);
}
}
exportReq.send( exportParms+"&"+form.toQueryString() );
exportReq.send(exportParms+"&"+form.toQueryString());
$('exportLog').spin();
}
}
@ -265,7 +265,7 @@ function updateFilterSelectors() {
Object.each(options,
function( values, key ) {
var selector = $('filter['+key+']');
if ( ! selector ) {
if ( !selector ) {
if ( window.console && window.console.log ) {
window.console.log('No selector found for ' + key);
}

View File

@ -131,9 +131,36 @@ function initPage() {
document.querySelectorAll('select[name="newMonitor[ControlId]"]').forEach(function(el) {
el.onchange = window['loadLocations'].bind(el, el);
});
document.querySelectorAll('input[name="newMonitor[WebColour]"]').forEach(function(el) {
el.onchange = window['change_WebColour'].bind(el);
});
$j('.chosen').chosen();
} // end function initPage()
function change_WebColour() {
$j('#WebSwatch').css(
'backgroundColor',
$j('input[name="newMonitor[WebColour]"]').val()
);
}
function getRandomColour() {
var letters = '0123456789ABCDEF';
var colour = '#';
for (var i = 0; i < 6; i++) {
colour += letters[Math.floor(Math.random() * 16)];
}
return colour;
}
function random_WebColour() {
var new_colour = getRandomColour();
$j('input[name="newMonitor[WebColour]"]').val(new_colour);
$j('#WebSwatch').css(
'backgroundColor', new_colour
);
}
window.addEventListener('DOMContentLoaded', initPage);

View File

@ -35,7 +35,7 @@ monitorData[monitorData.length] = {
'connKey': <?php echo $monitor->connKey() ?>,
'width': <?php echo $monitor->ViewWidth() ?>,
'height':<?php echo $monitor->ViewHeight() ?>,
'url': '<?php echo $monitor->UrlToIndex( $monitor->Id() + ZM_MIN_STREAMING_PORT) ?>',
'url': '<?php echo $monitor->UrlToIndex( ZM_MIN_STREAMING_PORT ? ($monitor->Id() + ZM_MIN_STREAMING_PORT) : '') ?>',
'onclick': function(){createPopup( '?view=watch&mid=<?php echo $monitor->Id() ?>', 'zmWatch<?php echo $monitor->Id() ?>', 'watch', <?php echo reScale( $monitor->ViewWidth(), $monitor->PopupScale() ); ?>, <?php echo reScale( $monitor->ViewHeight(), $monitor->PopupScale() ); ?> );},
'type': '<?php echo $monitor->Type() ?>',
'refresh': '<?php echo $monitor->Refresh() ?>'

View File

@ -18,7 +18,7 @@ var speedIndex=<?php echo $speedIndex?>;
// for history, and fps for live, and dynamically determined (in ms)
var currentDisplayInterval=<?php echo $initialDisplayInterval?>;
var playSecsperInterval=1; // How many seconds of recorded image we play per refresh determined by speed (replay rate) and display interval; (default=1 if coming from live)
var playSecsPerInterval=1; // How many seconds of recorded image we play per refresh determined by speed (replay rate) and display interval; (default=1 if coming from live)
var timerInterval; // milliseconds between interrupts
var timerObj; // object to hold timer interval;
var freeTimeLastIntervals=[]; // Percentage of current interval used in loading most recent image

View File

@ -11,12 +11,15 @@
(
function () {
// Append '?(GET query)' to URL if the GET query is not empty.
var querySuffix = "<?php
if (!empty($_POST['postLoginQuery'])) {
parse_str($_POST['postLoginQuery'], $queryParams);
var querySuffix = '<?php
if (!empty($_SESSION['postLoginQuery'])) {
parse_str($_SESSION['postLoginQuery'], $queryParams);
echo '?' . http_build_query($queryParams);
zm_session_start();
unset($_SESSION['postLoginQuery']);
session_write_close();
}
?>";
?>';
if ( querySuffix == '?view=login' ) {
// If we didn't redirect elsewhere, then don't show login page, go to console

View File

@ -54,7 +54,7 @@ $j(document).ready(function() {
url: thisUrl,
data: formData,
dataType: 'html',
enocde: true
timeout: 0
}).done(function(data) {
location.reload();
});

View File

@ -184,7 +184,7 @@ function tlZoomBounds( minTime, maxTime ) {
}
function tlZoomOut() {
location.replace('?view='+currentView+filterQuery+'&midTime='+midTime+'&range='+zoom_range);
location.replace('?view='+currentView+filterQuery+'&midTime='+midTime+'&range='+zoomout_range);
}
function tlPanLeft() {

View File

@ -44,17 +44,17 @@ function changeScale() {
newHeight = monitorHeight * scale / SCALE_BASE;
}
Cookie.write( 'zmWatchScale'+monitorId, scale, {duration: 10*365} );
Cookie.write('zmWatchScale'+monitorId, scale, {duration: 10*365});
/*Stream could be an applet so can't use moo tools*/
var streamImg = $('liveStream'+monitorId);
if ( streamImg ) {
streamImg.style.width = newWidth + "px";
streamImg.style.height = newHeight + "px";
streamImg.style.width = newWidth + 'px';
streamImg.style.height = newHeight + 'px';
streamImg.src = streamImg.src.replace(/scale=\d+/i, 'scale='+(scale== 'auto' ? autoScale : scale));
} else {
console.error("No element found for liveStream.");
console.error('No element found for liveStream.');
}
}
@ -64,17 +64,17 @@ var lastAlarmState = STATE_IDLE;
function setAlarmState( currentAlarmState ) {
alarmState = currentAlarmState;
var stateClass = "";
var stateClass = '';
if ( alarmState == STATE_ALARM ) {
stateClass = "alarm";
stateClass = 'alarm';
} else if ( alarmState == STATE_ALERT ) {
stateClass = "alert";
stateClass = 'alert';
}
$('stateValue').set( 'text', stateStrings[alarmState] );
$('stateValue').set('text', stateStrings[alarmState]);
if ( stateClass ) {
$('stateValue').setProperty( 'class', stateClass );
$('stateValue').setProperty('class', stateClass);
} else {
$('stateValue').removeProperty( 'class' );
$('stateValue').removeProperty('class');
}
var isAlarmed = ( alarmState == STATE_ALARM || alarmState == STATE_ALERT );
@ -114,7 +114,7 @@ function setAlarmState( currentAlarmState ) {
}
if ( monitorType != 'WebSite' ) {
var streamCmdParms = "view=request&request=stream&connkey="+connKey;
var streamCmdParms = 'view=request&request=stream&connkey='+connKey;
if ( auth_hash ) {
streamCmdParms += '&auth='+auth_hash;
}
@ -141,7 +141,7 @@ function getStreamCmdFailure(xhr) {
console.log(xhr);
}
function getStreamCmdResponse(respObj, respText) {
watchdogOk("stream");
watchdogOk('stream');
if ( streamCmdTimer ) {
streamCmdTimer = clearTimeout(streamCmdTimer);
}
@ -229,12 +229,18 @@ function getStreamCmdResponse(respObj, respText) {
} // end if canEditMonitors
if ( streamStatus.auth ) {
auth_hash = streamStatus.auth;
console.log("Have a new auth hash" + streamStatus.auth);
// Try to reload the image stream.
var streamImg = $('liveStream');
if ( streamImg ) {
streamImg.src = streamImg.src.replace(/auth=\w+/i, 'auth='+streamStatus.auth);
}
streamCmdParms = streamCmdParms.replace(/auth=\w+/i, 'auth='+streamStatus.auth);
statusCmdParms = statusCmdParms.replace(/auth=\w+/i, 'auth='+streamStatus.auth);
eventCmdParms = eventCmdParms.replace(/auth=\w+/i, 'auth='+streamStatus.auth);
actParms = actParms.replace(/auth=\w+/i, 'auth='+streamStatus.auth);
controlParms = controlParms.replace(/auth=\w+/i, 'auth='+streamStatus.auth);
} // end if have a new auth hash
} // end if respObj.status
} else {
@ -473,6 +479,9 @@ function getActResponse( respObj, respText ) {
function deleteEvent( event, eventId ) {
var actParms = "view=request&request=event&action=delete&id="+eventId;
if ( auth_hash ) {
actParms += '&auth='+auth_hash;
}
var actReq = new Request.JSON( {
url: thisUrl,
method: 'post',

View File

@ -122,9 +122,12 @@ xhtmlHeaders(__FILE__, translate('SystemLog') );
<form id="exportForm" action="" method="post">
<fieldset>
<legend><?php echo translate('SelectLog') ?></legend>
<label for="selectorAll"><?php echo translate('All') ?></label><input type="radio" id="selectorAll" name="selector" value="all"/>
<label for="selectorFilter"><?php echo translate('Filter') ?></label><input type="radio" id="selectorFilter" name="selector" value="filter"/>
<label for="selectorCurrent"><?php echo translate('Current') ?></label><input type="radio" id="selectorCurrent" name="selector" value="current" title="<?php echo translate('ChooseLogSelection') ?>" data-validators="validate-one-required"/>
<label for="selectorAll"><?php echo translate('All') ?></label>
<input type="radio" id="selectorAll" name="selector" value="all"/>
<label for="selectorFilter"><?php echo translate('Filter') ?></label>
<input type="radio" id="selectorFilter" name="selector" value="filter"/>
<label for="selectorCurrent"><?php echo translate('Current') ?></label>
<input type="radio" id="selectorCurrent" name="selector" value="current" title="<?php echo translate('ChooseLogSelection') ?>" data-validators="validate-one-required"/>
</fieldset>
<fieldset>
<legend><?php echo translate('SelectFormat') ?></legend>

View File

@ -7,7 +7,6 @@ xhtmlHeaders(__FILE__, translate('Login'));
<form class="center-block" name="loginForm" id="loginForm" method="post" action="?">
<input type="hidden" name="action" value="login"/>
<input type="hidden" name="view" value="login"/>
<input type="hidden" name="postLoginQuery" value="<?php echo isset($_SERVER['QUERY_STRING']) ? htmlspecialchars($_SERVER['QUERY_STRING']) : ''?>">
<div id="loginError" class="hidden alarm" role="alert">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>

View File

@ -40,8 +40,8 @@ if ( !empty($_REQUEST['mid']) ) {
if ( $monitor and ZM_OPT_X10 )
$x10Monitor = dbFetchOne('SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($_REQUEST['mid']));
}
if ( !$monitor ) {
if ( !$monitor ) {
$nextId = getTableAutoInc('Monitors');
if ( isset($_REQUEST['dupId']) ) {
$monitor = new ZM\Monitor($_REQUEST['dupId']);
@ -54,6 +54,7 @@ if ( !$monitor ) {
$monitor = new ZM\Monitor();
} # end if $_REQUEST['dupID']
$monitor->Name(translate('Monitor').'-'.$nextId);
$monitor->WebColour(random_colour());
} # end if $_REQUEST['mid']
if ( ZM_OPT_X10 && empty($x10Monitor) ) {
@ -67,7 +68,6 @@ if ( ZM_OPT_X10 && empty($x10Monitor) ) {
function fourcc($a, $b, $c, $d) {
return ord($a) | (ord($b) << 8) | (ord($c) << 16) | (ord($d) << 24);
}
if ( isset($_REQUEST['newMonitor']) ) {
# Update the monitor object with whatever has been set so far.
$monitor->set($_REQUEST['newMonitor']);
@ -371,13 +371,6 @@ $label_size = array(
'Large' => 2
);
$savejpegopts = array(
'Disabled' => 0,
'Frames only' => 1,
'Analysis images only (if available)' => 2,
'Frames + Analysis images (if available)' => 3,
);
$codecs = array(
'auto' => translate('Auto'),
'MP4' => translate('MP4'),
@ -459,8 +452,8 @@ foreach ( $tabs as $name=>$value ) {
if ( $tab != 'general' ) {
?>
<input type="hidden" name="newMonitor[Name]" value="<?php echo validHtmlStr($monitor->Name()) ?>"/>
<input type="hidden" name="newMonitor[Notes]" value="<?php echo validHtmlStr($monitor->Notes()) ?>"/>
<input type="hidden" name="newMonitor[ServerId]" value="<?php echo validHtmlStr($monitor->ServerId() ) ?>"/>
<input type="hidden" name="newMonitor[StorageId]" value="<?= validHtmlStr($monitor->StorageId() ) ?>"/>
<input type="hidden" name="newMonitor[LinkedMonitors]" value="<?php echo (null !== $monitor->LinkedMonitors())?validHtmlStr($monitor->LinkedMonitors()):'' ?>"/>
<?php
foreach ( $monitor->GroupIds() as $group_id ) {
@ -529,6 +522,7 @@ if ( $tab != 'source' ) {
}
if ( $tab != 'storage' ) {
?>
<input type="hidden" name="newMonitor[StorageId]" value="<?php echo validHtmlStr($monitor->StorageId()) ?>"/>
<input type="hidden" name="newMonitor[SaveJPEGs]" value="<?php echo validHtmlStr($monitor->SaveJPEGs()) ?>"/>
<input type="hidden" name="newMonitor[VideoWriter]" value="<?php echo validHtmlStr($monitor->VideoWriter()) ?>"/>
<input type="hidden" name="newMonitor[EncoderParameters]" value="<?php echo validHtmlStr($monitor->EncoderParameters()) ?>"/>
@ -612,6 +606,10 @@ switch ( $tab ) {
<td><?php echo translate('Name') ?></td>
<td><input type="text" name="newMonitor[Name]" value="<?php echo validHtmlStr($monitor->Name()) ?>"/></td>
</tr>
<tr class="Notes">
<td><?php echo translate('Notes') ?></td>
<td><textarea name="newMonitor[Notes]" rows="4"><?php echo validHtmlStr($monitor->Notes()) ?></textarea></td>
</tr>
<tr>
<td><?php echo translate('Server') ?></td><td>
<?php
@ -620,18 +618,6 @@ switch ( $tab ) {
$servers[$Server->Id()] = $Server->Name();
}
echo htmlSelect( 'newMonitor[ServerId]', $servers, $monitor->ServerId() );
?>
</td>
</tr>
<tr>
<td><?php echo translate('StorageArea') ?></td>
<td>
<?php
$storage_areas = array(0=>'Default');
foreach ( ZM\Storage::find(NULL, array('order'=>'lower(Name)')) as $Storage ) {
$storage_areas[$Storage->Id()] = $Storage->Name();
}
echo htmlSelect('newMonitor[StorageId]', $storage_areas, $monitor->StorageId());
?>
</td>
</tr>
@ -845,13 +831,13 @@ include('_monitor_source_nvsocket.php');
?>
<tr class="DecoderHWAccelName">
<td><?php echo translate('DecoderHWAccelName') ?>
(<?php echo makePopupLink('?view=optionhelp&amp;option=DECODERHWACCELNAME', 'zmOptionHelp', 'optionhelp', '?') ?>)
(<?php echo makePopupLink('?view=optionhelp&amp;option=OPTIONS_DECODERHWACCELNAME', 'zmOptionHelp', 'optionhelp', '?') ?>)
</td>
<td><input type="text" name="newMonitor[DecoderHWAccelName]" value="<?php echo validHtmlStr($monitor->DecoderHWAccelName()) ?>"/></td>
</tr>
<tr class="DecoderHWAccelDevice">
<td><?php echo translate('DecoderHWAccelDevice') ?>
(<?php echo makePopupLink('?view=optionhelp&amp;option=DECODERHWACCELDEVIC', 'zmOptionHelp', 'optionhelp', '?') ?>)
(<?php echo makePopupLink('?view=optionhelp&amp;option=OPTIONS_DECODERHWACCELDEVICE', 'zmOptionHelp', 'optionhelp', '?') ?>)
</td>
<td><input type="text" name="newMonitor[DecoderHWAccelDevice]" value="<?php echo validHtmlStr($monitor->DecoderHWAccelDevice()) ?>"/></td>
</tr>
@ -886,6 +872,7 @@ if ( $monitor->Type() != 'NVSocket' && $monitor->Type() != 'WebSite' ) {
'1920x1080'=>'1920x1080 1080p',
'2048x1536'=>'2048x1536 3MP',
'2592x1944'=>'2592x1944 5MP',
'3840x2160'=>'3840x2160 4K UHD',
), $monitor->Width().'x'.$monitor->Height()
);
?>
@ -921,7 +908,32 @@ 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 validHtmlStr($value); ?>"<?php if ( $value == $monitor->SaveJPEGs() ) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($name); ?></option><?php } ?></select></td></tr>
<tr>
<td><?php echo translate('StorageArea') ?></td>
<td>
<?php
$storage_areas = array(0=>'Default');
foreach ( ZM\Storage::find(NULL, array('order'=>'lower(Name)')) as $Storage ) {
$storage_areas[$Storage->Id()] = $Storage->Name();
}
echo htmlSelect('newMonitor[StorageId]', $storage_areas, $monitor->StorageId());
?>
</td>
</tr>
<tr>
<td><?php echo translate('SaveJPEGs') ?></td>
<td>
<?php
$savejpegopts = array(
0 => 'Disabled',
1 => 'Frames only',
2 => 'Analysis images only (if available)',
3 => 'Frames + Analysis images (if available)',
);
echo htmlSelect('newMonitor[SaveJPEGs]', $savejpegopts, $monitor->SaveJPEGs());
?>
</td>
</tr>
<tr><td><?php echo translate('VideoWriter') ?></td><td>
<?php
$videowriteropts = array(
@ -1102,15 +1114,17 @@ if ( canEdit('Control') ) {
<tr>
<td><?php echo translate('SignalCheckColour') ?></td>
<td>
<input type="text" name="newMonitor[SignalCheckColour]" value="<?php echo validHtmlStr($monitor->SignalCheckColour()) ?>"/>
<input type="color" name="newMonitor[SignalCheckColour]" value="<?php echo validHtmlStr($monitor->SignalCheckColour()) ?>"/>
<span id="SignalCheckSwatch" class="swatch" style="background-color: <?php echo validHtmlStr($monitor->SignalCheckColour()); ?>;">&nbsp;&nbsp;&nbsp;&nbsp;</span>
</td>
</tr>
<tr>
<td><?php echo translate('WebColour') ?></td>
<td>
<input type="text" name="newMonitor[WebColour]" value="<?php echo validHtmlStr($monitor->WebColour()) ?>" onchange="$('WebSwatch').setStyle( 'backgroundColor', this.value )"/>
<input type="color" name="newMonitor[WebColour]" value="<?php echo validHtmlStr($monitor->WebColour()) ?>"/>
<span id="WebSwatch" class="swatch" style="background-color: <?php echo validHtmlStr($monitor->WebColour()) ?>;">&nbsp;&nbsp;&nbsp;&nbsp;</span>
<i class="material-icons" data-on-click="random_WebColour">sync</i>
</td>
</tr>
<tr>

View File

@ -247,18 +247,18 @@ function probeNetwork() {
$arp_command = ZM_PATH_ARP;
$result = explode(' ', $arp_command);
if ( !is_executable($result[0]) ) {
ZM\Error("ARP compatible binary not found or not executable by the web user account. Verify ZM_PATH_ARP points to a valid arp tool.");
return;
ZM\Error('ARP compatible binary not found or not executable by the web user account. Verify ZM_PATH_ARP points to a valid arp tool.');
return $cameras;
}
$result = exec(escapeshellcmd($arp_command), $output, $status);
if ( $status ) {
ZM\Error("Unable to probe network cameras, status is '$status'");
return;
return $cameras;
}
$monitors = array();
foreach ( dbFetchAll("SELECT Id, Name, Host FROM Monitors WHERE Type = 'Remote' ORDER BY Host") as $monitor ) {
foreach ( dbFetchAll("SELECT `Id`, `Name`, `Host` FROM `Monitors` WHERE `Type` = 'Remote' ORDER BY `Host`") as $monitor ) {
if ( preg_match('/^(.+)@(.+)$/', $monitor['Host'], $matches) ) {
//echo "1: ".$matches[2]." = ".gethostbyname($matches[2])."<br/>";
$monitors[gethostbyname($matches[2])] = $monitor;
@ -277,29 +277,29 @@ function probeNetwork() {
'78:a5:dd' => array('type'=>'Wansview','probeFunc'=>'probeWansview')
);
foreach ( $output as $line ) {
if ( !preg_match('/(\d+\.\d+\.\d+\.\d+).*(([0-9a-f]{2}:){5})/', $line, $matches) )
continue;
$ip = $matches[1];
$host = $ip;
$mac = $matches[2];
//echo "I:$ip, H:$host, M:$mac<br/>";
$macRoot = substr($mac,0,8);
if ( isset($macBases[$macRoot]) ) {
$macBase = $macBases[$macRoot];
$camera = call_user_func($macBase['probeFunc'], $ip);
$sourceDesc = base64_encode(serialize($camera['monitor']));
$sourceString = $camera['model'].' @ '.$host;
if ( isset($monitors[$ip]) ) {
$monitor = $monitors[$ip];
$sourceString .= ' ('.$monitor['Name'].')';
} else {
$sourceString .= ' - '.translate('Available');
}
$cameras[$sourceDesc] = $sourceString;
foreach ( $output as $line ) {
if ( !preg_match('/(\d+\.\d+\.\d+\.\d+).*(([0-9a-f]{2}:){5})/', $line, $matches) )
continue;
$ip = $matches[1];
$host = $ip;
$mac = $matches[2];
//echo "I:$ip, H:$host, M:$mac<br/>";
$macRoot = substr($mac,0,8);
if ( isset($macBases[$macRoot]) ) {
$macBase = $macBases[$macRoot];
$camera = call_user_func($macBase['probeFunc'], $ip);
$sourceDesc = base64_encode(serialize($camera['monitor']));
$sourceString = $camera['model'].' @ '.$host;
if ( isset($monitors[$ip]) ) {
$monitor = $monitors[$ip];
$sourceString .= ' ('.$monitor['Name'].')';
} else {
$sourceString .= ' - '.translate('Available');
}
} # end foreach output line
return $cameras;
$cameras[$sourceDesc] = $sourceString;
}
} # end foreach output line
return $cameras;
} # end function probeNetwork()
$cameras = array();

View File

@ -110,8 +110,6 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*',GLOB_ONLYDIR)) as $
<button value="Save" type="submit"><?php echo translate('Save') ?></button>
</div>
</form>
<?php
} else if ( $tab == 'users' ) {
?>
@ -278,15 +276,10 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*',GLOB_ONLYDIR)) as $
<td class="colPath"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Path()), $canEdit ) ?></td>
<td class="colType"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Type()), $canEdit ) ?></td>
<td class="colScheme"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Scheme()), $canEdit ) ?></td>
<td class="colServer"><?php
echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Server()->Name()), $canEdit ) ?></td>
<td class="colDiskSpace">
<?php echo
human_filesize($Storage->disk_used_space()) . ' of ' . human_filesize($Storage->disk_total_space())
?>
</td>
<td class="ColEvents"><?php echo count($Storage->Events()).' using '.human_filesize($Storage->event_disk_space()) ?></td>
<td class="colMark"><input type="checkbox" name="markIds[]" value="<?php echo $Storage->Id() ?>" data-on-click-this="configureDeleteButton"<?php if ( count($Storage->Events()) or !$canEdit ) { ?> disabled="disabled"<?php } ?><?php echo count($Storage->Events()) ? ' title="Can\' delete as long as there are events stored here."' : ''?>/></td>
<td class="colServer"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Server()->Name()), $canEdit ) ?></td>
<td class="colDiskSpace"><?php echo human_filesize($Storage->disk_used_space()) . ' of ' . human_filesize($Storage->disk_total_space()) ?></td>
<td class="ColEvents"><?php echo $Storage->EventCount().' using '.human_filesize($Storage->event_disk_space()) ?></td>
<td class="colMark"><input type="checkbox" name="markIds[]" value="<?php echo $Storage->Id() ?>" data-on-click-this="configureDeleteButton"<?php if ( $Storage->EventCount() or !$canEdit ) { ?> disabled="disabled"<?php } ?><?php echo $Storage->EventCount() ? ' title="Can\'t delete as long as there are events stored here."' : ''?>/></td>
</tr>
<?php } #end foreach Server ?>
</tbody>
@ -319,23 +312,28 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*',GLOB_ONLYDIR)) as $
}
function updateSelected() {
# Turn them all off, then selectively turn the checked ones back on
dbQuery('UPDATE `Users` SET `APIEnabled`=0');
foreach ( $_REQUEST["tokenUids"] as $markUid ) {
$minTime = time();
dbQuery('UPDATE `Users` SET `TokenMinExpiry`=? WHERE `Id`=?', array($minTime, $markUid));
if ( isset($_REQUEST['tokenUids']) ) {
foreach ( $_REQUEST['tokenUids'] as $markUid ) {
$minTime = time();
dbQuery('UPDATE `Users` SET `TokenMinExpiry`=? WHERE `Id`=?', array($minTime, $markUid));
}
}
foreach ( $_REQUEST["apiUids"] as $markUid ) {
dbQuery('UPDATE `Users` SET `APIEnabled`=1 WHERE `Id`=?', array($markUid));
if ( isset($_REQUEST['apiUids']) ) {
foreach ( $_REQUEST['apiUids'] as $markUid ) {
dbQuery('UPDATE `Users` SET `APIEnabled`=1 WHERE `Id`=?', array($markUid));
}
}
echo '<span class="timedSuccessBox">'.translate('Updated').'</span>';
}
if ( array_key_exists('revokeAllTokens',$_POST) ) {
if ( array_key_exists('revokeAllTokens', $_POST) ) {
revokeAllTokens();
}
if ( array_key_exists('updateSelected',$_POST) ) {
if ( array_key_exists('updateSelected', $_POST) ) {
updateSelected();
}
?>

View File

@ -24,7 +24,11 @@ if ( !canEdit('System') ) {
}
?>
<div id="modalState" class="modal fade">
<form class="form-horizontal" name="contentForm" id="contentForm" method="get" action="?view=state">
<form class="form-horizontal" name="contentForm" method="get" action="?view=state">
<input type="hidden" name="view" value="state"/>
<input type="hidden" name="action" value="state"/>
<input type="hidden" name="apply" value="1"/>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
@ -32,9 +36,6 @@ if ( !canEdit('System') ) {
<h2 class="modal-title"><?php echo translate('RunState') ?></h2>
</div>
<div class="modal-body">
<input type="hidden" name="view" value="state"/>
<input type="hidden" name="action" value="state"/>
<input type="hidden" name="apply" value="1"/>
<div class="form-group">
<label for="runState" class="col-sm-3 control-label">Change State</label>