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

This commit is contained in:
Isaac Connor 2020-01-05 17:28:50 -05:00
commit fd633a2175
62 changed files with 1335 additions and 1170 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;

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.14
Version: 1.33.16
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,6 +416,9 @@ 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
* Sun Aug 11 2019 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.33.14-1
- Bump to 1.33.13 Development

View File

@ -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
,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
#
@ -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;

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

@ -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

@ -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

@ -10,6 +10,7 @@ FFmpeg_Input::FFmpeg_Input() {
FFMPEGInit();
streams = NULL;
frame = NULL;
last_seek_request = -1;
}
FFmpeg_Input::~FFmpeg_Input() {
@ -102,7 +103,6 @@ int FFmpeg_Input::Open(const char *filepath) {
} // end int FFmpeg_Input::Open( const char * filepath )
AVFrame *FFmpeg_Input::get_frame(int stream_id) {
Debug(1, "Getting frame from stream %d", stream_id);
int frameComplete = false;
AVPacket packet;
@ -138,12 +138,14 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id) {
frame = zm_av_frame_alloc();
}
ret = zm_send_packet_receive_frame(context, frame, packet);
if ( ret <= 0 ) {
if ( ret < 0 ) {
Error("Unable to decode frame at frame %d: %s, continuing",
streams[packet.stream_index].frame_count, av_make_error_string(ret).c_str());
zm_av_packet_unref(&packet);
av_frame_free(&frame);
continue;
} else {
zm_dump_frame(frame, "resulting frame");
}
frameComplete = 1;
@ -175,9 +177,20 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id, double at) {
}
// Have to grab a frame to update our current frame to know where we are
get_frame(stream_id);
} // end if ! frame
} // end if ! frame
if ( frame->pts > seek_target ) {
if ( !frame ) {
Warning("Unable to get frame.");
return NULL;
}
if (
(last_seek_request >= 0)
&&
(last_seek_request > seek_target )
&&
(frame->pts > seek_target)
) {
zm_dump_frame(frame, "frame->pts > seek_target, seek backwards");
// our frame must be beyond our seek target. so go backwards to before it
if ( ( ret = av_seek_frame(input_format_context, stream_id, seek_target,
@ -191,6 +204,8 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id, double at) {
zm_dump_frame(frame, "frame->pts > seek_target, got");
} // end if frame->pts > seek_target
last_seek_request = seek_target;
// Seeking seems to typically seek to a keyframe, so then we have to decode until we get the frame we want.
if ( frame->pts <= seek_target ) {
zm_dump_frame(frame, "pts <= seek_target");

View File

@ -42,6 +42,7 @@ class FFmpeg_Input {
int audio_stream_id;
AVFormatContext *input_format_context;
AVFrame *frame;
int64_t last_seek_request;
};
#endif

View File

@ -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 )
@ -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 {
@ -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];
@ -671,8 +680,12 @@ void MonitorStream::runStream() {
zm_terminate = true;
}
// Perhaps we should use NOW instead.
memcpy(&last_frame_timestamp, snap->timestamp, sizeof(last_frame_timestamp));
//frame_sent = true;
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,21 +731,21 @@ 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++;
@ -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 );
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 );
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 );
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 );
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

@ -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,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,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.33.16

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

@ -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,25 @@ 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'],
//),
//)
);
}
)
);
$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

@ -51,10 +51,10 @@ class Event extends ZM_Object {
if ( $new ) {
$this->{'Storage'} = $new;
}
if ( ! ( array_key_exists('Storage', $this) and $this->{'Storage'} ) ) {
if ( ! ( property_exists($this, 'Storage') and $this->{'Storage'} ) ) {
if ( isset($this->{'StorageId'}) and $this->{'StorageId'} )
$this->{'Storage'} = Storage::find_one(array('Id'=>$this->{'StorageId'}));
if ( ! ( array_key_exists('Storage', $this) and $this->{'Storage'} ) )
if ( ! ( property_exists($this, 'Storage') and $this->{'Storage'} ) )
$this->{'Storage'} = new Storage(NULL);
}
return $this->{'Storage'};
@ -64,10 +64,10 @@ class Event extends ZM_Object {
if ( $new ) {
$this->{'SecondaryStorage'} = $new;
}
if ( ! ( array_key_exists('SecondaryStorage', $this) and $this->{'SecondaryStorage'} ) ) {
if ( ! ( property_exists($this, 'SecondaryStorage') and $this->{'SecondaryStorage'} ) ) {
if ( isset($this->{'SecondaryStorageId'}) and $this->{'SecondaryStorageId'} )
$this->{'SecondaryStorage'} = Storage::find_one(array('Id'=>$this->{'SecondaryStorageId'}));
if ( ! ( array_key_exists('SecondaryStorage', $this) and $this->{'SecondaryStorage'} ) )
if ( ! ( property_exists($this, 'SecondaryStorage') and $this->{'SecondaryStorage'} ) )
$this->{'SecondaryStorage'} = new Storage(NULL);
}
return $this->{'SecondaryStorage'};
@ -262,7 +262,7 @@ class Event extends ZM_Object {
if ( is_null($new) or ( $new != '' ) ) {
$this->{'DiskSpace'} = $new;
}
if ( (!array_key_exists('DiskSpace',$this)) or (null === $this->{'DiskSpace'}) ) {
if ( (!property_exists($this, 'DiskSpace')) or (null === $this->{'DiskSpace'}) ) {
$this->{'DiskSpace'} = folder_size($this->Path());
dbQuery('UPDATE Events SET DiskSpace=? WHERE Id=?', array($this->{'DiskSpace'}, $this->{'Id'}));
}
@ -298,7 +298,7 @@ class Event extends ZM_Object {
} // end function createListThumbnail
function ThumbnailWidth( ) {
if ( ! ( array_key_exists('ThumbnailWidth', $this) ) ) {
if ( ! ( property_exists($this, 'ThumbnailWidth') ) ) {
if ( ZM_WEB_LIST_THUMB_WIDTH ) {
$this->{'ThumbnailWidth'} = ZM_WEB_LIST_THUMB_WIDTH;
$scale = (SCALE_BASE*ZM_WEB_LIST_THUMB_WIDTH)/$this->{'Width'};
@ -315,7 +315,7 @@ class Event extends ZM_Object {
} // end function ThumbnailWidth
function ThumbnailHeight( ) {
if ( ! ( array_key_exists('ThumbnailHeight', $this) ) ) {
if ( ! ( property_exists($this, 'ThumbnailHeight') ) ) {
if ( ZM_WEB_LIST_THUMB_WIDTH ) {
$this->{'ThumbnailWidth'} = ZM_WEB_LIST_THUMB_WIDTH;
$scale = (SCALE_BASE*ZM_WEB_LIST_THUMB_WIDTH)/$this->{'Width'};

View File

@ -39,8 +39,8 @@ class Filter extends ZM_Object {
$this->{'Query'} = func_get_arg(0);;
$this->{'Query_json'} = jsonEncode($this->{'Query'});
}
if ( !array_key_exists('Query', $this) ) {
if ( array_key_exists('Query_json', $this) and $this->{'Query_json'} ) {
if ( !property_exists($this, 'Query') ) {
if ( property_exists($this, 'Query_json') and $this->{'Query_json'} ) {
$this->{'Query'} = jsonDecode($this->{'Query_json'});
} else {
$this->{'Query'} = array();

View File

@ -18,7 +18,7 @@ class Group extends ZM_Object {
}
public function delete() {
if ( array_key_exists('Id', $this) ) {
if ( property_exists($this, 'Id') ) {
dbQuery('DELETE FROM Groups_Monitors WHERE GroupId=?', array($this->{'Id'}));
dbQuery('UPDATE Groups SET ParentId=NULL WHERE ParentId=?', array($this->{'Id'}));
dbQuery('DELETE FROM Groups WHERE Id=?', array($this->{'Id'}));
@ -35,7 +35,7 @@ class Group extends ZM_Object {
if ( isset($new) ) {
$this->{'depth'} = $new;
}
if ( !array_key_exists('depth', $this) or ($this->{'depth'} === null) ) {
if ( !property_exists($this, 'depth') or ($this->{'depth'} === null) ) {
$this->{'depth'} = 0;
if ( $this->{'ParentId'} != null ) {
$Parent = Group::find_one(array('Id'=>$this->{'ParentId'}));
@ -46,7 +46,7 @@ class Group extends ZM_Object {
} // end public function depth
public function MonitorIds( ) {
if ( ! array_key_exists('MonitorIds', $this) ) {
if ( ! property_exists($this, 'MonitorIds') ) {
$this->{'MonitorIds'} = dbFetchAll('SELECT MonitorId FROM Groups_Monitors WHERE GroupId=?', 'MonitorId', array($this->{'Id'}));
}
return $this->{'MonitorIds'};

View File

@ -9,118 +9,119 @@ 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 ( !array_key_exists('Control', $this) ) {
if ( !property_exists($this, 'Control') ) {
if ( $this->ControlId() )
$this->{'Control'} = Control::find_one(array('Id'=>$this->{'ControlId'}));
if ( !(array_key_exists('Control', $this) and $this->{'Control'}) )
if ( !(property_exists($this, 'Control') and $this->{'Control'}) )
$this->{'Control'} = new Control();
}
return $this->{'Control'};
@ -138,7 +139,7 @@ private $status_fields = array(
$this->{$fn} = $args[0];
}
}
if ( array_key_exists($fn, $this) ) {
if ( property_exists($this, $fn) ) {
return $this->{$fn};
} else if ( array_key_exists($fn, $this->defaults) ) {
if ( is_array($this->defaults[$fn]) ) {
@ -211,9 +212,9 @@ private $status_fields = array(
$this->{'Width'} = $new;
$field = ( $this->Orientation() == 'ROTATE_90' or $this->Orientation() == 'ROTATE_270' ) ? 'Height' : 'Width';
if ( array_key_exists($field, $this) )
if ( property_exists($this, $field) )
return $this->{$field};
return $this->defaults{$field};
return $this->defaults[$field];
} // end function Width
public function ViewHeight($new=null) {
@ -221,9 +222,9 @@ private $status_fields = array(
$this->{'Height'} = $new;
$field = ( $this->Orientation() == 'ROTATE_90' or $this->Orientation() == 'ROTATE_270' ) ? 'Width' : 'Height';
if ( array_key_exists($field, $this) )
if ( property_exists($this, $field) )
return $this->{$field};
return $this->defaults{$field};
return $this->defaults[$field];
} // end function Height
public function SignalCheckColour($new=null) {
@ -234,10 +235,10 @@ private $status_fields = array(
// Validate that it's a valid colour (we seem to allow color names, not just hex).
// This also helps prevent XSS.
if (array_key_exists($field, $this) && preg_match('/^[#0-9a-zA-Z]+$/', $this->{$field})) {
if ( property_exists($this, $field) && preg_match('/^[#0-9a-zA-Z]+$/', $this->{$field})) {
return $this->{$field};
}
return $this->defaults{$field};
return $this->defaults[$field];
} // end function SignalCheckColour
public static function find( $parameters = array(), $options = array() ) {
@ -253,7 +254,7 @@ private $status_fields = array(
Warning('Attempt to control a monitor with no Id');
return;
}
if ( (!defined('ZM_SERVER_ID')) or ( array_key_exists('ServerId', $this) and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) {
if ( (!defined('ZM_SERVER_ID')) or ( property_exists($this, 'ServerId') and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) {
if ( $this->Type() == 'Local' ) {
$zmcArgs = '-d '.$this->{'Device'};
} else {
@ -306,7 +307,7 @@ private $status_fields = array(
return;
}
if ( (!defined('ZM_SERVER_ID')) or ( array_key_exists('ServerId', $this) and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) {
if ( (!defined('ZM_SERVER_ID')) or ( property_exists($this, 'ServerId') and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) {
if ( $this->{'Function'} == 'None' || $this->{'Function'} == 'Monitor' || $mode == 'stop' ) {
if ( ZM_OPT_CONTROL ) {
daemonControl('stop', 'zmtrack.pl', '-m '.$this->{'Id'});
@ -367,8 +368,8 @@ private $status_fields = array(
}
}
if ( !array_key_exists('GroupIds', $this) ) {
if ( array_key_exists('Id', $this) and $this->{'Id'} ) {
if ( !property_exists($this, 'GroupIds') ) {
if ( property_exists($this, 'Id') and $this->{'Id'} ) {
$this->{'GroupIds'} = dbFetchAll('SELECT `GroupId` FROM `Groups_Monitors` WHERE `MonitorId`=?', 'GroupId', array($this->{'Id'}) );
if ( ! $this->{'GroupIds'} )
$this->{'GroupIds'} = array();
@ -417,7 +418,7 @@ private $status_fields = array(
if ( $new ) {
$this->{'Storage'} = $new;
}
if ( ! ( array_key_exists('Storage', $this) and $this->{'Storage'} ) ) {
if ( ! ( property_exists($this, 'Storage') and $this->{'Storage'} ) ) {
$this->{'Storage'} = isset($this->{'StorageId'}) ?
Storage::find_one(array('Id'=>$this->{'StorageId'})) :
new Storage(NULL);
@ -467,58 +468,58 @@ private $status_fields = array(
return $source;
} // end function Source
public function UrlToIndex() {
return $this->Server()->UrlToIndex();
public function UrlToIndex($port=null) {
return $this->Server()->UrlToIndex($port);
//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 ( array_key_exists('ServerId', $this) 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';

View File

@ -1,133 +1,22 @@
<?php
namespace ZM;
require_once('Object.php');
require_once('database.php');
class MontageLayout {
private $defaults = array(
class MontageLayout extends ZM_Object {
protected static $table = 'MontageLayouts';
protected $defaults = array(
'Id' => null,
'Name' => '',
'Positions' => 0,
);
public function __construct( $IdOrRow = NULL ) {
if ( $IdOrRow ) {
$row = NULL;
if ( is_integer( $IdOrRow ) or is_numeric( $IdOrRow ) ) {
$row = dbFetchOne( 'SELECT * FROM MontageLayouts WHERE Id=?', NULL, array( $IdOrRow ) );
if ( ! $row ) {
Error("Unable to load MontageLayout record for Id=" . $IdOrRow );
}
} else if ( is_array( $IdOrRow ) ) {
$row = $IdOrRow;
} else {
Error("Unknown argument passed to MontageLayout Constructor ($IdOrRow)");
return;
}
if ( $row ) {
foreach ($row as $k => $v) {
$this->{$k} = $v;
}
} else {
Error('No row for MontageLayout ' . $IdOrRow );
}
} # end if isset($IdOrRow)
} // end function __construct
public function __call($fn, array $args){
if ( count($args) ) {
$this->{$fn} = $args[0];
}
if ( array_key_exists($fn, $this) ) {
return $this->{$fn};
} else {
if ( array_key_exists( $fn, $this->defaults ) ) {
return $this->defaults{$fn};
} else {
$backTrace = debug_backtrace();
$file = $backTrace[1]['file'];
$line = $backTrace[1]['line'];
Warning( "Unknown function call MontageLayout->$fn from $file:$line" );
}
}
public static function find( $parameters = array(), $options = array() ) {
return ZM_Object::_find(get_class(), $parameters, $options);
}
public function set( $data ) {
foreach ($data as $k => $v) {
if ( is_array( $v ) ) {
# perhaps should turn into a comma-separated string
$this->{$k} = implode(',',$v);
} else if ( is_string( $v ) ) {
$this->{$k} = trim( $v );
} else if ( is_integer( $v ) ) {
$this->{$k} = $v;
} else if ( is_bool( $v ) ) {
$this->{$k} = $v;
} else {
Error( "Unknown type $k => $v of var " . gettype( $v ) );
$this->{$k} = $v;
}
}
public static function find_one( $parameters = array(), $options = array() ) {
return ZM_Object::_find_one(get_class(), $parameters, $options);
}
public static function find( $parameters = null, $options = null ) {
$filters = array();
$sql = 'SELECT * FROM MontageLayouts ';
$values = array();
if ( $parameters ) {
$fields = array();
$sql .= 'WHERE ';
foreach ( $parameters as $field => $value ) {
if ( $value == null ) {
$fields[] = $field.' IS NULL';
} else if ( is_array( $value ) ) {
$func = function(){return '?';};
$fields[] = $field.' IN ('.implode(',', array_map( $func, $value ) ). ')';
$values += $value;
} else {
$fields[] = $field.'=?';
$values[] = $value;
}
}
$sql .= implode(' AND ', $fields );
}
if ( $options and isset($options['order']) ) {
$sql .= ' ORDER BY ' . $options['order'];
}
$result = dbQuery($sql, $values);
if ( $result ) {
$results = $result->fetchALL();
foreach ( $results as $row ) {
$filters[] = new MontageLayout($row);
}
}
return $filters;
}
public function save( $new_values = null ) {
if ( $new_values ) {
foreach ( $new_values as $k=>$v ) {
$this->{$k} = $v;
}
}
$fields = array_values( array_filter( array_keys($this->defaults), function($field){return $field != 'Id';} ) );
$values = null;
if ( isset($this->{'Id'}) ) {
$sql = 'UPDATE MontageLayouts SET '.implode(', ', array_map( function($field) {return $field.'=?';}, $fields ) ) . ' WHERE Id=?';
$values = array_map( function($field){return $this->{$field};}, $fields );
$values[] = $this->{'Id'};
dbQuery($sql, $values);
} else {
$sql = 'INSERT INTO MontageLayouts ('.implode( ',', $fields ).') VALUES ('.implode(',',array_map( function(){return '?';}, $fields ) ).')';
$values = array_map( function($field){return $this->{$field};}, $fields );
dbQuery($sql, $values);
global $dbConn;
$this->{'Id'} = $dbConn->lastInsertId();
}
} // end function save
} // end class MontageLayout
?>

View File

@ -45,7 +45,7 @@ class ZM_Object {
$this->{$fn} = $args[0];
}
if ( array_key_exists($fn, $this) ) {
if ( property_exists($this, $fn) ) {
return $this->{$fn};
} else {
if ( array_key_exists($fn, $this->defaults) ) {
@ -140,10 +140,10 @@ class ZM_Object {
foreach ($this->defaults as $key => $value) {
if ( is_callable(array($this, $key)) ) {
$json[$key] = $this->$key();
} else if ( array_key_exists($key, $this) ) {
} else if ( property_exists($this, $key) ) {
$json[$key] = $this->{$key};
} else {
$json[$key] = $this->defaults{$key};
$json[$key] = $this->defaults[$key];
}
}
return json_encode($json);
@ -158,14 +158,24 @@ class ZM_Object {
# perhaps should turn into a comma-separated string
$this->{$k} = implode(',', $v);
} else if ( is_string($v) ) {
if ( $v == '' and array_key_exists($k, $this->defaults) ) {
if ( is_array($this->defaults[$k]) )
if ( 0 ) {
# Remarking this out. We are setting a value, not asking for a default to be set.
# So don't do defaults here, do them somewhere else
if ( ($v == null) and array_key_exists($k, $this->defaults) ) {
Logger::Debug("$k => Have default for $v: ");
if ( is_array($this->defaults[$k]) ) {
$this->{$k} = $this->defaults[$k]['default'];
else
$this->{$k} = $this->defaults[$k];
} else {
$this->{$k} = trim($v);
} else {
$this->{$k} = $this->defaults[$k];
Logger::Debug("$k => Have default for $v: " . $this->{$k});
}
} else {
$this->{$k} = trim($v);
}
} else {
$this->{$k} = trim($v);
}
} else if ( is_integer($v) ) {
$this->{$k} = $v;
} else if ( is_bool($v) ) {
@ -215,7 +225,7 @@ class ZM_Object {
} else if ( $this->$field() != $value ) {
$changes[$field] = $value;
}
} else if ( array_key_exists($field, $this) ) {
} else if ( property_exists($this, $field) ) {
$type = (array_key_exists($field, $this->defaults) && is_array($this->defaults[$field])) ? $this->defaults[$field]['type'] : 'scalar';
Logger::Debug("Checking field $field => current ".
(is_array($this->{$field}) ? implode(',',$this->{$field}) : $this->{$field}) . ' ?= ' .

View File

@ -80,7 +80,7 @@ class Storage extends ZM_Object {
}
public function disk_total_space() {
if ( !array_key_exists('disk_total_space', $this) ) {
if ( !property_exists($this, 'disk_total_space') ) {
$path = $this->Path();
if ( file_exists($path) ) {
$this->{'disk_total_space'} = disk_total_space($path);
@ -94,7 +94,7 @@ class Storage extends ZM_Object {
public function disk_used_space() {
# This isn't a function like this in php, so we have to add up the space used in each event.
if ( ( !array_key_exists('disk_used_space', $this)) or !$this->{'disk_used_space'} ) {
if ( ( !property_exists($this, 'disk_used_space')) or !$this->{'disk_used_space'} ) {
if ( $this->{'Type'} == 's3fs' ) {
$this->{'disk_used_space'} = $this->event_disk_space();
} else {
@ -112,7 +112,7 @@ class Storage extends ZM_Object {
public function event_disk_space() {
# This isn't a function like this in php, so we have to add up the space used in each event.
if ( (! array_key_exists('DiskSpace', $this)) or (!$this->{'DiskSpace'}) ) {
if ( (! property_exists($this, 'DiskSpace')) or (!$this->{'DiskSpace'}) ) {
$used = dbFetchOne('SELECT SUM(DiskSpace) AS DiskSpace FROM Events WHERE StorageId=? AND DiskSpace IS NOT NULL', 'DiskSpace', array($this->Id()));
do {
@ -130,8 +130,8 @@ class Storage extends ZM_Object {
} // end function event_disk_space
public function Server() {
if ( ! array_key_exists('Server',$this) ) {
if ( array_key_exists('ServerId', $this) ) {
if ( ! property_exists($this, 'Server') ) {
if ( property_exists($this, 'ServerId') ) {
$this->{'Server'} = Server::find_one(array('Id'=>$this->{'ServerId'}));
if ( !$this->{'Server'} ) {

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

@ -39,7 +39,7 @@ if ( $action == 'function' ) {
$oldFunction = $monitor['Function'];
$oldEnabled = $monitor['Enabled'];
if ( $newFunction != $oldFunction || $newEnabled != $oldEnabled ) {
dbQuery('UPDATE Monitors SET Function=?, Enabled=? WHERE Id=?',
dbQuery('UPDATE Monitors SET `Function`=?, `Enabled`=? WHERE `Id`=?',
array($newFunction, $newEnabled, $mid));
$monitor['Function'] = $newFunction;

View File

@ -31,19 +31,19 @@ if ( $action == 'state' ) {
}
} else if ( $action == 'save' ) {
if ( !empty($_REQUEST['runState']) || !empty($_REQUEST['newState']) ) {
$sql = 'SELECT Id,Function,Enabled FROM Monitors ORDER BY Id';
$sql = 'SELECT `Id`,`Function`,`Enabled` FROM Monitors ORDER BY Id';
$definitions = array();
foreach( dbFetchAll($sql) as $monitor ) {
foreach ( dbFetchAll($sql) as $monitor ) {
$definitions[] = $monitor['Id'].':'.$monitor['Function'].':'.$monitor['Enabled'];
}
$definition = join(',', $definitions);
if ( $_REQUEST['newState'] )
$_REQUEST['runState'] = $_REQUEST['newState'];
dbQuery('REPLACE INTO States SET Name=?, Definition=?', array($_REQUEST['runState'],$definition));
dbQuery('REPLACE INTO `States` SET `Name`=?, `Definition`=?', array($_REQUEST['runState'],$definition));
}
} else if ( $action == 'delete' ) {
if ( isset($_REQUEST['runState']) )
dbQuery('DELETE FROM States WHERE Name=?', array($_REQUEST['runState']));
dbQuery('DELETE FROM `States` WHERE `Name`=?', array($_REQUEST['runState']));
}
$view = 'console';
?>

View File

@ -220,19 +220,19 @@ function generateAuthHash($useRemoteAddr, $force=false) {
function visibleMonitor($mid) {
global $user;
return ( empty($user['MonitorIds']) || in_array($mid, explode(',', $user['MonitorIds'])) );
return ( $user && empty($user['MonitorIds']) || in_array($mid, explode(',', $user['MonitorIds'])) );
}
function canView($area, $mid=false) {
global $user;
return ( ($user[$area] == 'View' || $user[$area] == 'Edit') && ( !$mid || visibleMonitor($mid) ) );
return ( $user && ($user[$area] == 'View' || $user[$area] == 'Edit') && ( !$mid || visibleMonitor($mid) ) );
}
function canEdit($area, $mid=false) {
global $user;
return ( $user[$area] == 'Edit' && ( !$mid || visibleMonitor($mid) ));
return ( $user && ($user[$area] == 'Edit') && ( !$mid || visibleMonitor($mid) ));
}
function userFromSession() {

View File

@ -33,9 +33,9 @@ $configFile = ZM_CONFIG;
$localConfigFile = basename($configFile);
if ( file_exists( $localConfigFile ) && filesize( $localConfigFile ) > 0 ) {
if ( php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR']) )
print( "Warning, overriding installed $localConfigFile file with local copy\n" );
print("Warning, overriding installed $localConfigFile file with local copy\n");
else
error_log( "Warning, overriding installed $localConfigFile file with local copy" );
error_log("Warning, overriding installed $localConfigFile file with local copy");
$configFile = $localConfigFile;
}
@ -49,19 +49,19 @@ if ( is_dir($configSubFolder) ) {
if ( is_readable($configSubFolder) ) {
foreach ( glob("$configSubFolder/*.conf") as $filename ) {
//error_log("processing $filename");
$configvals = array_replace($configvals, process_configfile($filename) );
$configvals = array_replace($configvals, process_configfile($filename));
}
} else {
error_log( "WARNING: ZoneMinder configuration subfolder found but is not readable. Check folder permissions on $configSubFolder." );
error_log("WARNING: ZoneMinder configuration subfolder found but is not readable. Check folder permissions on $configSubFolder.");
}
} else {
error_log( "WARNING: ZoneMinder configuration subfolder found but is not a directory. Check $configSubFolder." );
error_log("WARNING: ZoneMinder configuration subfolder found but is not a directory. Check $configSubFolder.");
}
# Now that our array our finalized, define each key => value
# pair in the array as a constant
foreach( $configvals as $key => $value) {
define( $key, $value );
foreach ( $configvals as $key => $value ) {
define($key, $value);
}
//
@ -135,8 +135,8 @@ define( 'SCALE_BASE', 100 ); // The additional scalin
define( 'STRF_FMT_DATETIME_DB', '%Y-%m-%d %H:%M:%S' ); // Strftime format for database queries, don't change
define( 'MYSQL_FMT_DATETIME_SHORT', '%y/%m/%d %H:%i:%S' ); // MySQL date_format shorter format for dates with time
require_once( 'database.php' );
require_once( 'logger.php' );
require_once('database.php');
require_once('logger.php');
loadConfig();
ZM\Logger::fetch()->initialise();
@ -165,28 +165,30 @@ function loadConfig( $defineConsts=true ) {
$result = $dbConn->query('SELECT Name,Value FROM Config');
if ( !$result )
echo mysql_error();
while( $row = dbFetchNext( $result ) ) {
while( $row = dbFetchNext($result) ) {
if ( $defineConsts )
define( $row['Name'], $row['Value'] );
define($row['Name'], $row['Value']);
$config[$row['Name']] = $row;
}
} # end function loadConfig
// For Human-readability, use ZM_SERVER_HOST or ZM_SERVER_NAME in zm.conf, and convert it here to a ZM_SERVER_ID
if ( ! defined('ZM_SERVER_ID') ) {
require_once('Server.php');
if ( defined('ZM_SERVER_NAME') and ZM_SERVER_NAME ) {
$server_id = dbFetchOne('SELECT Id FROM Servers WHERE Name=?', 'Id', array(ZM_SERVER_NAME));
if ( ! $server_id ) {
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.');
# Use Server lookup so that it caches
$Server = ZM\Server::find_one(array('Name'=>ZM_SERVER_NAME));
if ( !$Server ) {
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 );
define('ZM_SERVER_ID', $Server->Id());
}
} else if ( defined('ZM_SERVER_HOST') and ZM_SERVER_HOST ) {
$server_id = dbFetchOne('SELECT Id FROM Servers WHERE Name=?', 'Id', array(ZM_SERVER_HOST));
if ( ! $server_id ) {
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.');
$Server = ZM\Server::find_one(array('Name'=>ZM_SERVER_HOST));
if ( ! $Server ) {
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 );
define('ZM_SERVER_ID', $Server->Id());
}
}
}
@ -197,21 +199,22 @@ 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 ))
$str = fgets($cfg, 256);
if ( preg_match('/^\s*(#.*)?$/', $str) ) {
continue;
elseif ( preg_match( '/^\s*#/', $str ))
continue;
elseif ( preg_match( '/^\s*([^=\s]+)\s*=\s*[\'"]*(.*?)[\'"]*\s*$/', $str, $matches ))
} else if ( preg_match( '/^\s*([^=\s]+)\s*=\s*[\'"]*(.*?)[\'"]*\s*$/', $str, $matches )) {
$configvals[$matches[1]] = $matches[2];
} else {
ZM\Error("Malformed line in config $configFile\n$str");
}
}
fclose( $cfg );
return( $configvals );
fclose($cfg);
return $configvals;
} else {
error_log( "WARNING: ZoneMinder configuration file found but is not readable. Check file permissions on $configFile." );
return( false );
error_log("WARNING: ZoneMinder configuration file found but is not readable. Check file permissions on $configFile.");
return false;
}
}

View File

@ -110,16 +110,10 @@ function dbError($sql) {
function dbEscape( $string ) {
global $dbConn;
if ( version_compare(phpversion(), '4.3.0', '<'))
if ( get_magic_quotes_gpc() )
return $dbConn->quote(stripslashes($string));
else
return $dbConn->quote($string);
if ( version_compare(phpversion(), '5.4', '<=') and get_magic_quotes_gpc() )
return $dbConn->quote(stripslashes($string));
else
if ( get_magic_quotes_gpc() )
return $dbConn->quote(stripslashes($string));
else
return $dbConn->quote($string);
return $dbConn->quote($string);
}
function dbQuery($sql, $params=NULL) {
@ -212,6 +206,10 @@ function dbFetch($sql, $col=false) {
}
function dbFetchNext($result, $col=false) {
if ( !$result ) {
ZM\Error("dbFetchNext called on null result.");
return false;
}
if ( $dbRow = $result->fetch(PDO::FETCH_ASSOC) )
return $col ? $dbRow[$col] : $dbRow;
return false;

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
@ -1085,9 +1090,8 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&amp;') {
$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('No terms in filter');
ZM\Warning(print_r($backTrace, true));
ZM\Warning(print_r($filter, true));
}
if ( isset($terms) && count($terms) ) {
@ -1324,7 +1328,7 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&amp;') {
$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']).' ';
@ -1336,6 +1340,8 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&amp;') {
if ( $saveToSession ) {
$_SESSION['filter'] = $filter;
}
} else {
$filter['query'] = $querySep.urlencode('filter[Query][terms]=[]');
} // end if terms
#if ( 0 ) {
@ -2604,4 +2610,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

@ -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");
@ -960,12 +960,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

@ -389,8 +389,8 @@ if ( (!ZM_OPT_USE_AUTH) or $user ) {
<li class="Load"><i class="material-icons md-18">trending_up</i>&nbsp;<?php echo translate('Load') ?>: <?php echo getLoad() ?></li>
<i class="material-icons md-18">storage</i>
<?php
$connections = dbFetchOne( "SHOW status WHERE variable_name='threads_connected'", 'Value' );
$max_connections = dbFetchOne( "SHOW variables WHERE variable_name='max_connections'", 'Value' );
$connections = dbFetchOne('SHOW status WHERE variable_name=\'threads_connected\'', 'Value');
$max_connections = dbFetchOne('SHOW variables WHERE variable_name=\'max_connections\'', 'Value');
$percent_used = $max_connections ? 100 * $connections / $max_connections : 100;
echo '<li'. ( $percent_used > 90 ? ' class="warning"' : '' ).'>'.translate('DB').':'.$connections.'/'.$max_connections.'</li>';
?>
@ -398,8 +398,12 @@ if ( (!ZM_OPT_USE_AUTH) or $user ) {
<?php
$storage_areas = ZM\Storage::find();
$storage_paths = null;
$storage_areas_with_no_server_id = array();
foreach ( $storage_areas as $area ) {
$storage_paths[$area->Path()] = $area;
if ( ! $area->ServerId() ) {
$storage_areas_with_no_server_id[] = $area;
}
}
$func = function($S){
$class = '';
@ -415,9 +419,9 @@ if ( (!ZM_OPT_USE_AUTH) or $user ) {
'; };
#$func = function($S){ return '<span title="">'.$S->Name() . ': ' . $S->disk_usage_percent().'%' . '</span>'; };
if ( count($storage_areas) > 4 )
$storage_areas = ZM\Storage::find( array('ServerId'=>null) );
$storage_areas = $storage_areas_with_no_server_id;
if ( count($storage_areas) <= 4 )
echo implode( ', ', array_map ( $func, $storage_areas ) );
echo implode(', ', array_map($func, $storage_areas));
echo ' ' . ZM_PATH_MAP .': '. getDiskPercent(ZM_PATH_MAP).'%';
?></li>
</ul>

View File

@ -46,7 +46,7 @@ var popupSizes = {
'group': {'width': 760, 'height': 600},
'groups': {'width': 540, 'height': 420},
'image': {'addWidth': 48, 'addHeight': 80},
'log': {'width': 1080, 'height': 720},
'log': {'width': 1180, 'height': 720},
'login': {'width': 720, 'height': 480},
'logout': {'width': 260, 'height': 150},
'monitor': {'width': 800, 'height': 780},

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

@ -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

@ -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

@ -146,10 +146,12 @@ if ( openFilterWindow ) {
function thumbnail_onmouseover(event) {
var img = event.target;
img.src = '';
img.src = img.getAttribute('stream_src');
}
function thumbnail_onmouseout(event) {
var img = event.target;
img.src = '';
img.src = img.getAttribute('still_src');
}

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

@ -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() ?>',
'url': '<?php echo $monitor->UrlToIndex( $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

@ -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

@ -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

@ -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>
@ -921,7 +907,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 +1113,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

@ -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' ) {
?>
@ -319,23 +317,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));
}
foreach ( $_REQUEST["apiUids"] as $markUid ) {
dbQuery('UPDATE `Users` SET `APIEnabled`=1 WHERE `Id`=?', array($markUid));
if ( isset($_REQUEST['tokenUids']) ) {
foreach ( $_REQUEST['tokenUids'] as $markUid ) {
$minTime = time();
dbQuery('UPDATE `Users` SET `TokenMinExpiry`=? WHERE `Id`=?', array($minTime, $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>

View File

@ -69,6 +69,7 @@ if ( !isset($newZone) ) {
'Id' => 0,
'Name' => translate('New'),
'Type' => 'Active',
'Units' => 'Pixels',
'MonitorId' => $monitor->Id(),
'NumCoords' => 4,
'Coords' => sprintf('%d,%d %d,%d, %d,%d %d,%d', $minX, $minY, $maxX, $minY, $maxX, $maxY, $minX, $maxY),